Modified: 
websites/production/commons/content/proper/commons-csv/jacoco/org.apache.commons.csv/CSVFormat.java.html
==============================================================================
--- 
websites/production/commons/content/proper/commons-csv/jacoco/org.apache.commons.csv/CSVFormat.java.html
 (original)
+++ 
websites/production/commons/content/proper/commons-csv/jacoco/org.apache.commons.csv/CSVFormat.java.html
 Thu Feb  2 12:12:49 2023
@@ -49,7 +49,7 @@ import java.util.Objects;
 import java.util.Set;
 
 /**
- * Specifies the format of a CSV file and parses input.
+ * Specifies the format of a CSV file for parsing and writing.
  *
  * <h2>Using predefined formats</h2>
  *
@@ -154,11 +154,29 @@ import java.util.Set;
  * This makes your code impervious to changes in column order in the CSV file.
  * </p>
  *
- * <h2>Notes</h2>
+ * <h2>Serialization</h2>
+ * <p>
+ *   This class implements the {@link Serializable} interface with the 
following caveats:
+ * </p>
+ * <ul>
+ *   <li>This class will no longer implement Serializable in 
2.0.</li>
+ *   <li>Serialization is not supported from one version to the 
next.</li>
+ * </ul>
+ * <p>
+ *   The {@code serialVersionUID} values are:
+ * </p>
+ * <ul>
+ *   <li>Version 1.10.0: {@code 2L}</li>
+ *   <li>Version 1.9.0 through 1.0: {@code 1L}</li>
+ * </ul>
  *
+ * <h2>Notes</h2>
  * <p>
  * This class is immutable.
  * </p>
+ * <p>
+ * Not all settings are used for both parsing and writing.
+ * </p>
  */
 public final class CSVFormat implements Serializable {
 
@@ -175,7 +193,7 @@ public final class CSVFormat implements
          * @return a copy of the builder
          */
         public static Builder create() {
-<span class="nc" id="L178">            return new 
Builder(CSVFormat.DEFAULT);</span>
+<span class="fc" id="L196">            return new 
Builder(CSVFormat.DEFAULT);</span>
         }
 
         /**
@@ -185,11 +203,9 @@ public final class CSVFormat implements
          * @return a copy of the builder
          */
         public static Builder create(final CSVFormat csvFormat) {
-<span class="fc" id="L188">            return new Builder(csvFormat);</span>
+<span class="fc" id="L206">            return new Builder(csvFormat);</span>
         }
 
-        private boolean allowDuplicateHeaderNames;
-
         private boolean allowMissingColumnNames;
 
         private boolean autoFlush;
@@ -198,6 +214,8 @@ public final class CSVFormat implements
 
         private String delimiter;
 
+        private DuplicateHeaderMode duplicateHeaderMode;
+
         private Character escapeCharacter;
 
         private String[] headerComments;
@@ -226,27 +244,27 @@ public final class CSVFormat implements
 
         private boolean trim;
 
-<span class="fc" id="L229">        private Builder(final CSVFormat csvFormat) 
{</span>
-<span class="fc" id="L230">            this.delimiter = 
csvFormat.delimiter;</span>
-<span class="fc" id="L231">            this.quoteCharacter = 
csvFormat.quoteCharacter;</span>
-<span class="fc" id="L232">            this.quoteMode = 
csvFormat.quoteMode;</span>
-<span class="fc" id="L233">            this.commentMarker = 
csvFormat.commentMarker;</span>
-<span class="fc" id="L234">            this.escapeCharacter = 
csvFormat.escapeCharacter;</span>
-<span class="fc" id="L235">            this.ignoreSurroundingSpaces = 
csvFormat.ignoreSurroundingSpaces;</span>
-<span class="fc" id="L236">            this.allowMissingColumnNames = 
csvFormat.allowMissingColumnNames;</span>
-<span class="fc" id="L237">            this.ignoreEmptyLines = 
csvFormat.ignoreEmptyLines;</span>
-<span class="fc" id="L238">            this.recordSeparator = 
csvFormat.recordSeparator;</span>
-<span class="fc" id="L239">            this.nullString = 
csvFormat.nullString;</span>
-<span class="fc" id="L240">            this.headerComments = 
csvFormat.headerComments;</span>
-<span class="fc" id="L241">            this.headers = csvFormat.header;</span>
-<span class="fc" id="L242">            this.skipHeaderRecord = 
csvFormat.skipHeaderRecord;</span>
-<span class="fc" id="L243">            this.ignoreHeaderCase = 
csvFormat.ignoreHeaderCase;</span>
-<span class="fc" id="L244">            this.trailingDelimiter = 
csvFormat.trailingDelimiter;</span>
-<span class="fc" id="L245">            this.trim = csvFormat.trim;</span>
-<span class="fc" id="L246">            this.autoFlush = 
csvFormat.autoFlush;</span>
-<span class="fc" id="L247">            this.quotedNullString = 
csvFormat.quotedNullString;</span>
-<span class="fc" id="L248">            this.allowDuplicateHeaderNames = 
csvFormat.allowDuplicateHeaderNames;</span>
-<span class="fc" id="L249">        }</span>
+<span class="fc" id="L247">        private Builder(final CSVFormat csvFormat) 
{</span>
+<span class="fc" id="L248">            this.delimiter = 
csvFormat.delimiter;</span>
+<span class="fc" id="L249">            this.quoteCharacter = 
csvFormat.quoteCharacter;</span>
+<span class="fc" id="L250">            this.quoteMode = 
csvFormat.quoteMode;</span>
+<span class="fc" id="L251">            this.commentMarker = 
csvFormat.commentMarker;</span>
+<span class="fc" id="L252">            this.escapeCharacter = 
csvFormat.escapeCharacter;</span>
+<span class="fc" id="L253">            this.ignoreSurroundingSpaces = 
csvFormat.ignoreSurroundingSpaces;</span>
+<span class="fc" id="L254">            this.allowMissingColumnNames = 
csvFormat.allowMissingColumnNames;</span>
+<span class="fc" id="L255">            this.ignoreEmptyLines = 
csvFormat.ignoreEmptyLines;</span>
+<span class="fc" id="L256">            this.recordSeparator = 
csvFormat.recordSeparator;</span>
+<span class="fc" id="L257">            this.nullString = 
csvFormat.nullString;</span>
+<span class="fc" id="L258">            this.headerComments = 
csvFormat.headerComments;</span>
+<span class="fc" id="L259">            this.headers = csvFormat.headers;</span>
+<span class="fc" id="L260">            this.skipHeaderRecord = 
csvFormat.skipHeaderRecord;</span>
+<span class="fc" id="L261">            this.ignoreHeaderCase = 
csvFormat.ignoreHeaderCase;</span>
+<span class="fc" id="L262">            this.trailingDelimiter = 
csvFormat.trailingDelimiter;</span>
+<span class="fc" id="L263">            this.trim = csvFormat.trim;</span>
+<span class="fc" id="L264">            this.autoFlush = 
csvFormat.autoFlush;</span>
+<span class="fc" id="L265">            this.quotedNullString = 
csvFormat.quotedNullString;</span>
+<span class="fc" id="L266">            this.duplicateHeaderMode = 
csvFormat.duplicateHeaderMode;</span>
+<span class="fc" id="L267">        }</span>
 
         /**
          * Builds a new CSVFormat instance.
@@ -254,7 +272,7 @@ public final class CSVFormat implements
          * @return a new CSVFormat instance.
          */
         public CSVFormat build() {
-<span class="fc" id="L257">            return new CSVFormat(this);</span>
+<span class="fc" id="L275">            return new CSVFormat(this);</span>
         }
 
         /**
@@ -262,14 +280,16 @@ public final class CSVFormat implements
          *
          * @param allowDuplicateHeaderNames the duplicate header names 
behavior, true to allow, false to disallow.
          * @return This instance.
+         * @deprecated Use {@link 
#setDuplicateHeaderMode(DuplicateHeaderMode)}.
          */
+        @Deprecated
         public Builder setAllowDuplicateHeaderNames(final boolean 
allowDuplicateHeaderNames) {
-<span class="fc" id="L267">            this.allowDuplicateHeaderNames = 
allowDuplicateHeaderNames;</span>
-<span class="fc" id="L268">            return this;</span>
+<span class="fc bfc" id="L287" title="All 2 branches covered.">            
setDuplicateHeaderMode(allowDuplicateHeaderNames ? 
DuplicateHeaderMode.ALLOW_ALL : DuplicateHeaderMode.ALLOW_EMPTY);</span>
+<span class="fc" id="L288">            return this;</span>
         }
 
         /**
-         * Sets the missing column names behavior, {@code true} to allow 
missing column names in the header line, {@code false} to cause an
+         * Sets the parser missing column names behavior, {@code true} to 
allow missing column names in the header line, {@code false} to cause an
          * {@link IllegalArgumentException} to be thrown.
          *
          * @param allowMissingColumnNames the missing column names behavior, 
{@code true} to allow missing column names in the header line, {@code false} to
@@ -277,8 +297,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setAllowMissingColumnNames(final boolean 
allowMissingColumnNames) {
-<span class="fc" id="L280">            this.allowMissingColumnNames = 
allowMissingColumnNames;</span>
-<span class="fc" id="L281">            return this;</span>
+<span class="fc" id="L300">            this.allowMissingColumnNames = 
allowMissingColumnNames;</span>
+<span class="fc" id="L301">            return this;</span>
         }
 
         /**
@@ -288,8 +308,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setAutoFlush(final boolean autoFlush) {
-<span class="fc" id="L291">            this.autoFlush = autoFlush;</span>
-<span class="fc" id="L292">            return this;</span>
+<span class="fc" id="L311">            this.autoFlush = autoFlush;</span>
+<span class="fc" id="L312">            return this;</span>
         }
 
         /**
@@ -302,8 +322,8 @@ public final class CSVFormat implements
          * @throws IllegalArgumentException thrown if the specified character 
is a line break
          */
         public Builder setCommentMarker(final char commentMarker) {
-<span class="fc" id="L305">            
setCommentMarker(Character.valueOf(commentMarker));</span>
-<span class="fc" id="L306">            return this;</span>
+<span class="fc" id="L325">            
setCommentMarker(Character.valueOf(commentMarker));</span>
+<span class="fc" id="L326">            return this;</span>
         }
 
         /**
@@ -316,11 +336,11 @@ public final class CSVFormat implements
          * @throws IllegalArgumentException thrown if the specified character 
is a line break
          */
         public Builder setCommentMarker(final Character commentMarker) {
-<span class="fc bfc" id="L319" title="All 2 branches covered.">            if 
(isLineBreak(commentMarker)) {</span>
-<span class="fc" id="L320">                throw new 
IllegalArgumentException(&quot;The comment start marker character cannot be a 
line break&quot;);</span>
+<span class="fc bfc" id="L339" title="All 2 branches covered.">            if 
(isLineBreak(commentMarker)) {</span>
+<span class="fc" id="L340">                throw new 
IllegalArgumentException(&quot;The comment start marker character cannot be a 
line break&quot;);</span>
             }
-<span class="fc" id="L322">            this.commentMarker = 
commentMarker;</span>
-<span class="fc" id="L323">            return this;</span>
+<span class="fc" id="L342">            this.commentMarker = 
commentMarker;</span>
+<span class="fc" id="L343">            return this;</span>
         }
 
         /**
@@ -330,7 +350,7 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setDelimiter(final char delimiter) {
-<span class="fc" id="L333">            return 
setDelimiter(String.valueOf(delimiter));</span>
+<span class="fc" id="L353">            return 
setDelimiter(String.valueOf(delimiter));</span>
         }
 
         /**
@@ -340,11 +360,26 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setDelimiter(final String delimiter) {
-<span class="fc bfc" id="L343" title="All 2 branches covered.">            if 
(containsLineBreak(delimiter)) {</span>
-<span class="fc" id="L344">                throw new 
IllegalArgumentException(&quot;The delimiter cannot be a line 
break&quot;);</span>
+<span class="fc bfc" id="L363" title="All 2 branches covered.">            if 
(containsLineBreak(delimiter)) {</span>
+<span class="fc" id="L364">                throw new 
IllegalArgumentException(&quot;The delimiter cannot be a line 
break&quot;);</span>
+            }
+<span class="fc bfc" id="L366" title="All 2 branches covered.">            if 
(delimiter.isEmpty()) {</span>
+<span class="fc" id="L367">                throw new 
IllegalArgumentException(&quot;The delimiter cannot be empty&quot;);</span>
             }
-<span class="fc" id="L346">            this.delimiter = delimiter;</span>
-<span class="fc" id="L347">            return this;</span>
+<span class="fc" id="L369">            this.delimiter = delimiter;</span>
+<span class="fc" id="L370">            return this;</span>
+        }
+
+        /**
+         * Sets the duplicate header names behavior.
+         *
+         * @param duplicateHeaderMode the duplicate header names behavior
+         * @return This instance.
+         * @since 1.10.0
+         */
+        public Builder setDuplicateHeaderMode(final DuplicateHeaderMode 
duplicateHeaderMode) {
+<span class="fc" id="L381">          this.duplicateHeaderMode = 
Objects.requireNonNull(duplicateHeaderMode, 
&quot;duplicateHeaderMode&quot;);</span>
+<span class="fc" id="L382">          return this;</span>
         }
 
         /**
@@ -355,8 +390,8 @@ public final class CSVFormat implements
          * @throws IllegalArgumentException thrown if the specified character 
is a line break
          */
         public Builder setEscape(final char escapeCharacter) {
-<span class="fc" id="L358">            
setEscape(Character.valueOf(escapeCharacter));</span>
-<span class="fc" id="L359">            return this;</span>
+<span class="fc" id="L393">            
setEscape(Character.valueOf(escapeCharacter));</span>
+<span class="fc" id="L394">            return this;</span>
         }
 
         /**
@@ -367,11 +402,11 @@ public final class CSVFormat implements
          * @throws IllegalArgumentException thrown if the specified character 
is a line break
          */
         public Builder setEscape(final Character escapeCharacter) {
-<span class="fc bfc" id="L370" title="All 2 branches covered.">            if 
(isLineBreak(escapeCharacter)) {</span>
-<span class="fc" id="L371">                throw new 
IllegalArgumentException(&quot;The escape character cannot be a line 
break&quot;);</span>
+<span class="fc bfc" id="L405" title="All 2 branches covered.">            if 
(isLineBreak(escapeCharacter)) {</span>
+<span class="fc" id="L406">                throw new 
IllegalArgumentException(&quot;The escape character cannot be a line 
break&quot;);</span>
             }
-<span class="fc" id="L373">            this.escapeCharacter = 
escapeCharacter;</span>
-<span class="fc" id="L374">            return this;</span>
+<span class="fc" id="L408">            this.escapeCharacter = 
escapeCharacter;</span>
+<span class="fc" id="L409">            return this;</span>
         }
 
         /**
@@ -396,15 +431,13 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setHeader(final Class&lt;? extends Enum&lt;?&gt;&gt; 
headerEnum) {
-<span class="fc" id="L399">            String[] header = null;</span>
-<span class="fc bfc" id="L400" title="All 2 branches covered.">            if 
(headerEnum != null) {</span>
-<span class="fc" id="L401">                final Enum&lt;?&gt;[] enumValues = 
headerEnum.getEnumConstants();</span>
-<span class="fc" id="L402">                header = new 
String[enumValues.length];</span>
-<span class="fc bfc" id="L403" title="All 2 branches covered.">                
for (int i = 0; i &lt; enumValues.length; i++) {</span>
-<span class="fc" id="L404">                    header[i] = 
enumValues[i].name();</span>
-                }
+<span class="fc" id="L434">            String[] header = null;</span>
+<span class="fc bfc" id="L435" title="All 2 branches covered.">            if 
(headerEnum != null) {</span>
+<span class="fc" id="L436">                final Enum&lt;?&gt;[] enumValues = 
headerEnum.getEnumConstants();</span>
+<span class="fc" id="L437">                header = new 
String[enumValues.length];</span>
+<span class="fc" id="L438">                Arrays.setAll(header, i -&gt; 
enumValues[i].name());</span>
             }
-<span class="fc" id="L407">            return setHeader(header);</span>
+<span class="fc" id="L440">            return setHeader(header);</span>
         }
 
         /**
@@ -428,7 +461,7 @@ public final class CSVFormat implements
          * @throws SQLException SQLException if a database access error occurs 
or this method is called on a closed result set.
          */
         public Builder setHeader(final ResultSet resultSet) throws 
SQLException {
-<span class="fc bfc" id="L431" title="All 2 branches covered.">            
return setHeader(resultSet != null ? resultSet.getMetaData() : null);</span>
+<span class="fc bfc" id="L464" title="All 2 branches covered.">            
return setHeader(resultSet != null ? resultSet.getMetaData() : null);</span>
         }
 
         /**
@@ -452,15 +485,15 @@ public final class CSVFormat implements
          * @throws SQLException SQLException if a database access error occurs 
or this method is called on a closed result set.
          */
         public Builder setHeader(final ResultSetMetaData resultSetMetaData) 
throws SQLException {
-<span class="fc" id="L455">            String[] labels = null;</span>
-<span class="fc bfc" id="L456" title="All 2 branches covered.">            if 
(resultSetMetaData != null) {</span>
-<span class="fc" id="L457">                final int columnCount = 
resultSetMetaData.getColumnCount();</span>
-<span class="fc" id="L458">                labels = new 
String[columnCount];</span>
-<span class="fc bfc" id="L459" title="All 2 branches covered.">                
for (int i = 0; i &lt; columnCount; i++) {</span>
-<span class="fc" id="L460">                    labels[i] = 
resultSetMetaData.getColumnLabel(i + 1);</span>
+<span class="fc" id="L488">            String[] labels = null;</span>
+<span class="fc bfc" id="L489" title="All 2 branches covered.">            if 
(resultSetMetaData != null) {</span>
+<span class="fc" id="L490">                final int columnCount = 
resultSetMetaData.getColumnCount();</span>
+<span class="fc" id="L491">                labels = new 
String[columnCount];</span>
+<span class="fc bfc" id="L492" title="All 2 branches covered.">                
for (int i = 0; i &lt; columnCount; i++) {</span>
+<span class="fc" id="L493">                    labels[i] = 
resultSetMetaData.getColumnLabel(i + 1);</span>
                 }
             }
-<span class="fc" id="L463">            return setHeader(labels);</span>
+<span class="fc" id="L496">            return setHeader(labels);</span>
         }
 
         /**
@@ -483,8 +516,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setHeader(final String... header) {
-<span class="fc" id="L486">            this.headers = 
CSVFormat.clone(header);</span>
-<span class="fc" id="L487">            return this;</span>
+<span class="fc" id="L519">            this.headers = 
CSVFormat.clone(header);</span>
+<span class="fc" id="L520">            return this;</span>
         }
 
         /**
@@ -498,8 +531,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setHeaderComments(final Object... headerComments) {
-<span class="fc" id="L501">            this.headerComments = 
CSVFormat.clone(toStringArray(headerComments));</span>
-<span class="fc" id="L502">            return this;</span>
+<span class="fc" id="L534">            this.headerComments = 
CSVFormat.clone(toStringArray(headerComments));</span>
+<span class="fc" id="L535">            return this;</span>
         }
 
         /**
@@ -513,8 +546,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setHeaderComments(final String... headerComments) {
-<span class="fc" id="L516">            this.headerComments = 
CSVFormat.clone(headerComments);</span>
-<span class="fc" id="L517">            return this;</span>
+<span class="fc" id="L549">            this.headerComments = 
CSVFormat.clone(headerComments);</span>
+<span class="fc" id="L550">            return this;</span>
         }
 
         /**
@@ -526,19 +559,19 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setIgnoreEmptyLines(final boolean ignoreEmptyLines) {
-<span class="fc" id="L529">            this.ignoreEmptyLines = 
ignoreEmptyLines;</span>
-<span class="fc" id="L530">            return this;</span>
+<span class="fc" id="L562">            this.ignoreEmptyLines = 
ignoreEmptyLines;</span>
+<span class="fc" id="L563">            return this;</span>
         }
 
         /**
-         * Sets the case mapping behavior, {@code true} to access name/values, 
{@code false} to leave the mapping as is.
+         * Sets the parser case mapping behavior, {@code true} to access 
name/values, {@code false} to leave the mapping as is.
          *
          * @param ignoreHeaderCase the case mapping behavior, {@code true} to 
access name/values, {@code false} to leave the mapping as is.
          * @return This instance.
          */
         public Builder setIgnoreHeaderCase(final boolean ignoreHeaderCase) {
-<span class="fc" id="L540">            this.ignoreHeaderCase = 
ignoreHeaderCase;</span>
-<span class="fc" id="L541">            return this;</span>
+<span class="fc" id="L573">            this.ignoreHeaderCase = 
ignoreHeaderCase;</span>
+<span class="fc" id="L574">            return this;</span>
         }
 
         /**
@@ -548,8 +581,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setIgnoreSurroundingSpaces(final boolean 
ignoreSurroundingSpaces) {
-<span class="fc" id="L551">            this.ignoreSurroundingSpaces = 
ignoreSurroundingSpaces;</span>
-<span class="fc" id="L552">            return this;</span>
+<span class="fc" id="L584">            this.ignoreSurroundingSpaces = 
ignoreSurroundingSpaces;</span>
+<span class="fc" id="L585">            return this;</span>
         }
 
         /**
@@ -564,9 +597,9 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setNullString(final String nullString) {
-<span class="fc" id="L567">            this.nullString = nullString;</span>
-<span class="fc" id="L568">            this.quotedNullString = quoteCharacter 
+ nullString + quoteCharacter;</span>
-<span class="fc" id="L569">            return this;</span>
+<span class="fc" id="L600">            this.nullString = nullString;</span>
+<span class="fc" id="L601">            this.quotedNullString = quoteCharacter 
+ nullString + quoteCharacter;</span>
+<span class="fc" id="L602">            return this;</span>
         }
 
         /**
@@ -576,8 +609,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setQuote(final char quoteCharacter) {
-<span class="fc" id="L579">            
setQuote(Character.valueOf(quoteCharacter));</span>
-<span class="fc" id="L580">            return this;</span>
+<span class="fc" id="L612">            
setQuote(Character.valueOf(quoteCharacter));</span>
+<span class="fc" id="L613">            return this;</span>
         }
 
         /**
@@ -587,11 +620,11 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setQuote(final Character quoteCharacter) {
-<span class="fc bfc" id="L590" title="All 2 branches covered.">            if 
(isLineBreak(quoteCharacter)) {</span>
-<span class="fc" id="L591">                throw new 
IllegalArgumentException(&quot;The quoteChar cannot be a line 
break&quot;);</span>
+<span class="fc bfc" id="L623" title="All 2 branches covered.">            if 
(isLineBreak(quoteCharacter)) {</span>
+<span class="fc" id="L624">                throw new 
IllegalArgumentException(&quot;The quoteChar cannot be a line 
break&quot;);</span>
             }
-<span class="fc" id="L593">            this.quoteCharacter = 
quoteCharacter;</span>
-<span class="fc" id="L594">            return this;</span>
+<span class="fc" id="L626">            this.quoteCharacter = 
quoteCharacter;</span>
+<span class="fc" id="L627">            return this;</span>
         }
 
         /**
@@ -601,8 +634,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setQuoteMode(final QuoteMode quoteMode) {
-<span class="fc" id="L604">            this.quoteMode = quoteMode;</span>
-<span class="fc" id="L605">            return this;</span>
+<span class="fc" id="L637">            this.quoteMode = quoteMode;</span>
+<span class="fc" id="L638">            return this;</span>
         }
 
         /**
@@ -617,8 +650,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setRecordSeparator(final char recordSeparator) {
-<span class="fc" id="L620">            this.recordSeparator = 
String.valueOf(recordSeparator);</span>
-<span class="fc" id="L621">            return this;</span>
+<span class="fc" id="L653">            this.recordSeparator = 
String.valueOf(recordSeparator);</span>
+<span class="fc" id="L654">            return this;</span>
         }
 
         /**
@@ -633,8 +666,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setRecordSeparator(final String recordSeparator) {
-<span class="fc" id="L636">            this.recordSeparator = 
recordSeparator;</span>
-<span class="fc" id="L637">            return this;</span>
+<span class="fc" id="L669">            this.recordSeparator = 
recordSeparator;</span>
+<span class="fc" id="L670">            return this;</span>
         }
 
         /**
@@ -644,8 +677,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setSkipHeaderRecord(final boolean skipHeaderRecord) {
-<span class="fc" id="L647">            this.skipHeaderRecord = 
skipHeaderRecord;</span>
-<span class="fc" id="L648">            return this;</span>
+<span class="fc" id="L680">            this.skipHeaderRecord = 
skipHeaderRecord;</span>
+<span class="fc" id="L681">            return this;</span>
         }
 
         /**
@@ -655,8 +688,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setTrailingDelimiter(final boolean trailingDelimiter) {
-<span class="fc" id="L658">            this.trailingDelimiter = 
trailingDelimiter;</span>
-<span class="fc" id="L659">            return this;</span>
+<span class="fc" id="L691">            this.trailingDelimiter = 
trailingDelimiter;</span>
+<span class="fc" id="L692">            return this;</span>
         }
 
         /**
@@ -666,8 +699,8 @@ public final class CSVFormat implements
          * @return This instance.
          */
         public Builder setTrim(final boolean trim) {
-<span class="fc" id="L669">            this.trim = trim;</span>
-<span class="fc" id="L670">            return this;</span>
+<span class="fc" id="L702">            this.trim = trim;</span>
+<span class="fc" id="L703">            return this;</span>
         }
     }
 
@@ -676,78 +709,78 @@ public final class CSVFormat implements
      *
      * @since 1.2
      */
-<span class="fc" id="L679">    public enum Predefined {</span>
+<span class="fc" id="L712">    public enum Predefined {</span>
 
         /**
          * @see CSVFormat#DEFAULT
          */
-<span class="fc" id="L684">        Default(CSVFormat.DEFAULT),</span>
+<span class="fc" id="L717">        Default(CSVFormat.DEFAULT),</span>
 
         /**
          * @see CSVFormat#EXCEL
          */
-<span class="fc" id="L689">        Excel(CSVFormat.EXCEL),</span>
+<span class="fc" id="L722">        Excel(CSVFormat.EXCEL),</span>
 
         /**
          * @see CSVFormat#INFORMIX_UNLOAD
          * @since 1.3
          */
-<span class="fc" id="L695">        
InformixUnload(CSVFormat.INFORMIX_UNLOAD),</span>
+<span class="fc" id="L728">        
InformixUnload(CSVFormat.INFORMIX_UNLOAD),</span>
 
         /**
          * @see CSVFormat#INFORMIX_UNLOAD_CSV
          * @since 1.3
          */
-<span class="fc" id="L701">        
InformixUnloadCsv(CSVFormat.INFORMIX_UNLOAD_CSV),</span>
+<span class="fc" id="L734">        
InformixUnloadCsv(CSVFormat.INFORMIX_UNLOAD_CSV),</span>
 
         /**
          * @see CSVFormat#MONGODB_CSV
          * @since 1.7
          */
-<span class="fc" id="L707">        MongoDBCsv(CSVFormat.MONGODB_CSV),</span>
+<span class="fc" id="L740">        MongoDBCsv(CSVFormat.MONGODB_CSV),</span>
 
         /**
          * @see CSVFormat#MONGODB_TSV
          * @since 1.7
          */
-<span class="fc" id="L713">        MongoDBTsv(CSVFormat.MONGODB_TSV),</span>
+<span class="fc" id="L746">        MongoDBTsv(CSVFormat.MONGODB_TSV),</span>
 
         /**
          * @see CSVFormat#MYSQL
          */
-<span class="fc" id="L718">        MySQL(CSVFormat.MYSQL),</span>
+<span class="fc" id="L751">        MySQL(CSVFormat.MYSQL),</span>
 
         /**
          * @see CSVFormat#ORACLE
          */
-<span class="fc" id="L723">        Oracle(CSVFormat.ORACLE),</span>
+<span class="fc" id="L756">        Oracle(CSVFormat.ORACLE),</span>
 
         /**
          * @see CSVFormat#POSTGRESQL_CSV
          * @since 1.5
          */
-<span class="fc" id="L729">        
PostgreSQLCsv(CSVFormat.POSTGRESQL_CSV),</span>
+<span class="fc" id="L762">        
PostgreSQLCsv(CSVFormat.POSTGRESQL_CSV),</span>
 
         /**
          * @see CSVFormat#POSTGRESQL_CSV
          */
-<span class="fc" id="L734">        
PostgreSQLText(CSVFormat.POSTGRESQL_TEXT),</span>
+<span class="fc" id="L767">        
PostgreSQLText(CSVFormat.POSTGRESQL_TEXT),</span>
 
         /**
          * @see CSVFormat#RFC4180
          */
-<span class="fc" id="L739">        RFC4180(CSVFormat.RFC4180),</span>
+<span class="fc" id="L772">        RFC4180(CSVFormat.RFC4180),</span>
 
         /**
          * @see CSVFormat#TDF
          */
-<span class="fc" id="L744">        TDF(CSVFormat.TDF);</span>
+<span class="fc" id="L777">        TDF(CSVFormat.TDF);</span>
 
         private final CSVFormat format;
 
-<span class="fc" id="L748">        Predefined(final CSVFormat format) {</span>
-<span class="fc" id="L749">            this.format = format;</span>
-<span class="fc" id="L750">        }</span>
+<span class="fc" id="L781">        Predefined(final CSVFormat format) {</span>
+<span class="fc" id="L782">            this.format = format;</span>
+<span class="fc" id="L783">        }</span>
 
         /**
          * Gets the format.
@@ -755,12 +788,13 @@ public final class CSVFormat implements
          * @return the format.
          */
         public CSVFormat getFormat() {
-<span class="fc" id="L758">            return format;</span>
+<span class="fc" id="L791">            return format;</span>
         }
     }
 
     /**
-     * Standard Comma Separated Value format, as for {@link #RFC4180} but 
allowing empty lines.
+     * Standard Comma Separated Value format, as for {@link #RFC4180} but 
allowing
+     * empty lines.
      *
      * &lt;p&gt;
      * The {@link Builder} settings are:
@@ -770,13 +804,13 @@ public final class CSVFormat implements
      * &lt;li&gt;{@code setQuote('&quot;')}&lt;/li&gt;
      * &lt;li&gt;{@code setRecordSeparator(&quot;\r\n&quot;)}&lt;/li&gt;
      * &lt;li&gt;{@code setIgnoreEmptyLines(true)}&lt;/li&gt;
-     * &lt;li&gt;{@code setAllowDuplicateHeaderNames(true)}&lt;/li&gt;
+     * &lt;li&gt;{@code 
setDuplicateHeaderMode(DuplicateHeaderMode.ALLOW_ALL)}&lt;/li&gt;
      * &lt;/ul&gt;
      *
      * @see Predefined#Default
      */
-<span class="fc" id="L778">    public static final CSVFormat DEFAULT = new 
CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF, null, 
null, null, false, false, false,</span>
-            false, false, false, true);
+<span class="fc" id="L812">    public static final CSVFormat DEFAULT = new 
CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF, null, 
null, null, false, false, false,</span>
+            false, false, false, DuplicateHeaderMode.ALLOW_ALL);
 
     /**
      * Excel file format (using a comma as the value delimiter). Note that the 
actual value delimiter used by Excel is locale dependent, it might be necessary
@@ -799,7 +833,7 @@ public final class CSVFormat implements
      * &lt;li&gt;{@code setRecordSeparator(&quot;\r\n&quot;)}&lt;/li&gt;
      * &lt;li&gt;{@code setIgnoreEmptyLines(false)}&lt;/li&gt;
      * &lt;li&gt;{@code setAllowMissingColumnNames(true)}&lt;/li&gt;
-     * &lt;li&gt;{@code setAllowDuplicateHeaderNames(true)}&lt;/li&gt;
+     * &lt;li&gt;{@code 
setDuplicateHeaderMode(DuplicateHeaderMode.ALLOW_ALL)}&lt;/li&gt;
      * &lt;/ul&gt;
      * &lt;p&gt;
      * Note: This is currently like {@link #RFC4180} plus {@link 
Builder#setAllowMissingColumnNames(boolean) 
Builder#setAllowMissingColumnNames(true)} and
@@ -809,10 +843,10 @@ public final class CSVFormat implements
      * @see Predefined#Excel
      */
     // @formatter:off
-<span class="fc" id="L812">    public static final CSVFormat EXCEL = 
DEFAULT.builder()</span>
-<span class="fc" id="L813">            .setIgnoreEmptyLines(false)</span>
-<span class="fc" id="L814">            .setAllowMissingColumnNames(true)</span>
-<span class="fc" id="L815">            .build();</span>
+<span class="fc" id="L846">    public static final CSVFormat EXCEL = 
DEFAULT.builder()</span>
+<span class="fc" id="L847">            .setIgnoreEmptyLines(false)</span>
+<span class="fc" id="L848">            .setAllowMissingColumnNames(true)</span>
+<span class="fc" id="L849">            .build();</span>
     // @formatter:on
 
     /**
@@ -839,12 +873,12 @@ public final class CSVFormat implements
      * @since 1.3
      */
     // @formatter:off
-<span class="fc" id="L842">    public static final CSVFormat INFORMIX_UNLOAD = 
DEFAULT.builder()</span>
-<span class="fc" id="L843">            .setDelimiter(PIPE)</span>
-<span class="fc" id="L844">            .setEscape(BACKSLASH)</span>
-<span class="fc" id="L845">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L846">            .setRecordSeparator(LF)</span>
-<span class="fc" id="L847">            .build();</span>
+<span class="fc" id="L876">    public static final CSVFormat INFORMIX_UNLOAD = 
DEFAULT.builder()</span>
+<span class="fc" id="L877">            .setDelimiter(PIPE)</span>
+<span class="fc" id="L878">            .setEscape(BACKSLASH)</span>
+<span class="fc" id="L879">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L880">            .setRecordSeparator(LF)</span>
+<span class="fc" id="L881">            .build();</span>
     // @formatter:on
 
     /**
@@ -870,11 +904,11 @@ public final class CSVFormat implements
      * @since 1.3
      */
     // @formatter:off
-<span class="fc" id="L873">    public static final CSVFormat 
INFORMIX_UNLOAD_CSV = DEFAULT.builder()</span>
-<span class="fc" id="L874">            .setDelimiter(COMMA)</span>
-<span class="fc" id="L875">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L876">            .setRecordSeparator(LF)</span>
-<span class="fc" id="L877">            .build();</span>
+<span class="fc" id="L907">    public static final CSVFormat 
INFORMIX_UNLOAD_CSV = DEFAULT.builder()</span>
+<span class="fc" id="L908">            .setDelimiter(COMMA)</span>
+<span class="fc" id="L909">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L910">            .setRecordSeparator(LF)</span>
+<span class="fc" id="L911">            .build();</span>
     // @formatter:on
 
     /**
@@ -904,13 +938,13 @@ public final class CSVFormat implements
      * @since 1.7
      */
     // @formatter:off
-<span class="fc" id="L907">    public static final CSVFormat MONGODB_CSV = 
DEFAULT.builder()</span>
-<span class="fc" id="L908">            .setDelimiter(COMMA)</span>
-<span class="fc" id="L909">            .setEscape(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L910">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L911">            .setQuoteMode(QuoteMode.MINIMAL)</span>
-<span class="fc" id="L912">            .setSkipHeaderRecord(false)</span>
-<span class="fc" id="L913">            .build();</span>
+<span class="fc" id="L941">    public static final CSVFormat MONGODB_CSV = 
DEFAULT.builder()</span>
+<span class="fc" id="L942">            .setDelimiter(COMMA)</span>
+<span class="fc" id="L943">            .setEscape(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L944">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L945">            .setQuoteMode(QuoteMode.MINIMAL)</span>
+<span class="fc" id="L946">            .setSkipHeaderRecord(false)</span>
+<span class="fc" id="L947">            .build();</span>
     // @formatter:off
 
     /**
@@ -941,13 +975,13 @@ public final class CSVFormat implements
      * @since 1.7
      */
     // @formatter:off
-<span class="fc" id="L944">    public static final CSVFormat MONGODB_TSV = 
DEFAULT.builder()</span>
-<span class="fc" id="L945">            .setDelimiter(TAB)</span>
-<span class="fc" id="L946">            .setEscape(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L947">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L948">            .setQuoteMode(QuoteMode.MINIMAL)</span>
-<span class="fc" id="L949">            .setSkipHeaderRecord(false)</span>
-<span class="fc" id="L950">            .build();</span>
+<span class="fc" id="L978">    public static final CSVFormat MONGODB_TSV = 
DEFAULT.builder()</span>
+<span class="fc" id="L979">            .setDelimiter(TAB)</span>
+<span class="fc" id="L980">            .setEscape(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L981">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L982">            .setQuoteMode(QuoteMode.MINIMAL)</span>
+<span class="fc" id="L983">            .setSkipHeaderRecord(false)</span>
+<span class="fc" id="L984">            .build();</span>
     // @formatter:off
 
     /**
@@ -976,15 +1010,15 @@ public final class CSVFormat implements
      *      -data.html&lt;/a&gt;
      */
     // @formatter:off
-<span class="fc" id="L979">    public static final CSVFormat MYSQL = 
DEFAULT.builder()</span>
-<span class="fc" id="L980">            .setDelimiter(TAB)</span>
-<span class="fc" id="L981">            .setEscape(BACKSLASH)</span>
-<span class="fc" id="L982">            .setIgnoreEmptyLines(false)</span>
-<span class="fc" id="L983">            .setQuote(null)</span>
-<span class="fc" id="L984">            .setRecordSeparator(LF)</span>
-<span class="fc" id="L985">            .setNullString(&quot;\\N&quot;)</span>
-<span class="fc" id="L986">            
.setQuoteMode(QuoteMode.ALL_NON_NULL)</span>
-<span class="fc" id="L987">            .build();</span>
+<span class="fc" id="L1013">    public static final CSVFormat MYSQL = 
DEFAULT.builder()</span>
+<span class="fc" id="L1014">            .setDelimiter(TAB)</span>
+<span class="fc" id="L1015">            .setEscape(BACKSLASH)</span>
+<span class="fc" id="L1016">            .setIgnoreEmptyLines(false)</span>
+<span class="fc" id="L1017">            .setQuote(null)</span>
+<span class="fc" id="L1018">            .setRecordSeparator(LF)</span>
+<span class="fc" id="L1019">            
.setNullString(Constants.SQL_NULL_STRING)</span>
+<span class="fc" id="L1020">            
.setQuoteMode(QuoteMode.ALL_NON_NULL)</span>
+<span class="fc" id="L1021">            .build();</span>
     // @formatter:off
 
     /**
@@ -1015,16 +1049,16 @@ public final class CSVFormat implements
      * @since 1.6
      */
     // @formatter:off
-<span class="fc" id="L1018">    public static final CSVFormat ORACLE = 
DEFAULT.builder()</span>
-<span class="fc" id="L1019">            .setDelimiter(COMMA)</span>
-<span class="fc" id="L1020">            .setEscape(BACKSLASH)</span>
-<span class="fc" id="L1021">            .setIgnoreEmptyLines(false)</span>
-<span class="fc" id="L1022">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L1023">            .setNullString(&quot;\\N&quot;)</span>
-<span class="fc" id="L1024">            .setTrim(true)</span>
-<span class="fc" id="L1025">            
.setRecordSeparator(System.lineSeparator())</span>
-<span class="fc" id="L1026">            .setQuoteMode(QuoteMode.MINIMAL)</span>
-<span class="fc" id="L1027">            .build();</span>
+<span class="fc" id="L1052">    public static final CSVFormat ORACLE = 
DEFAULT.builder()</span>
+<span class="fc" id="L1053">            .setDelimiter(COMMA)</span>
+<span class="fc" id="L1054">            .setEscape(BACKSLASH)</span>
+<span class="fc" id="L1055">            .setIgnoreEmptyLines(false)</span>
+<span class="fc" id="L1056">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L1057">            
.setNullString(Constants.SQL_NULL_STRING)</span>
+<span class="fc" id="L1058">            .setTrim(true)</span>
+<span class="fc" id="L1059">            
.setRecordSeparator(System.lineSeparator())</span>
+<span class="fc" id="L1060">            .setQuoteMode(QuoteMode.MINIMAL)</span>
+<span class="fc" id="L1061">            .build();</span>
     // @formatter:off
 
     /**
@@ -1032,7 +1066,7 @@ public final class CSVFormat implements
      *
      * &lt;p&gt;
      * This is a comma-delimited format with a LF character as the line 
separator. Values are double quoted and special
-     * characters are escaped with {@code '&quot;'}. The default NULL string 
is {@code &quot;&quot;}.
+     * characters are not escaped. The default NULL string is {@code 
&quot;&quot;}.
      * &lt;/p&gt;
      *
      * &lt;p&gt;
@@ -1040,7 +1074,7 @@ public final class CSVFormat implements
      * &lt;/p&gt;
      * &lt;ul&gt;
      * &lt;li&gt;{@code setDelimiter(',')}&lt;/li&gt;
-     * &lt;li&gt;{@code setEscape('&quot;')}&lt;/li&gt;
+     * &lt;li&gt;{@code setEscape(null)}&lt;/li&gt;
      * &lt;li&gt;{@code setIgnoreEmptyLines(false)}&lt;/li&gt;
      * &lt;li&gt;{@code setQuote('&quot;')}&lt;/li&gt;
      * &lt;li&gt;{@code setRecordSeparator('\n')}&lt;/li&gt;
@@ -1054,23 +1088,23 @@ public final class CSVFormat implements
      * @since 1.5
      */
     // @formatter:off
-<span class="fc" id="L1057">    public static final CSVFormat POSTGRESQL_CSV = 
DEFAULT.builder()</span>
-<span class="fc" id="L1058">            .setDelimiter(COMMA)</span>
-<span class="fc" id="L1059">            .setEscape(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L1060">            .setIgnoreEmptyLines(false)</span>
-<span class="fc" id="L1061">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L1062">            .setRecordSeparator(LF)</span>
-<span class="fc" id="L1063">            .setNullString(EMPTY)</span>
-<span class="fc" id="L1064">            
.setQuoteMode(QuoteMode.ALL_NON_NULL)</span>
-<span class="fc" id="L1065">            .build();</span>
+<span class="fc" id="L1091">    public static final CSVFormat POSTGRESQL_CSV = 
DEFAULT.builder()</span>
+<span class="fc" id="L1092">            .setDelimiter(COMMA)</span>
+<span class="fc" id="L1093">            .setEscape(null)</span>
+<span class="fc" id="L1094">            .setIgnoreEmptyLines(false)</span>
+<span class="fc" id="L1095">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
+<span class="fc" id="L1096">            .setRecordSeparator(LF)</span>
+<span class="fc" id="L1097">            .setNullString(EMPTY)</span>
+<span class="fc" id="L1098">            
.setQuoteMode(QuoteMode.ALL_NON_NULL)</span>
+<span class="fc" id="L1099">            .build();</span>
     // @formatter:off
 
     /**
      * Default PostgreSQL text format used by the {@code COPY} operation.
      *
      * &lt;p&gt;
-     * This is a tab-delimited format with a LF character as the line 
separator. Values are double quoted and special
-     * characters are escaped with {@code '&quot;'}. The default NULL string 
is {@code &quot;\\N&quot;}.
+     * This is a tab-delimited format with a LF character as the line 
separator. Values are not quoted and special
+     * characters are escaped with {@code '\\'}. The default NULL string is 
{@code &quot;\\N&quot;}.
      * &lt;/p&gt;
      *
      * &lt;p&gt;
@@ -1080,7 +1114,7 @@ public final class CSVFormat implements
      * &lt;li&gt;{@code setDelimiter('\t')}&lt;/li&gt;
      * &lt;li&gt;{@code setEscape('\\')}&lt;/li&gt;
      * &lt;li&gt;{@code setIgnoreEmptyLines(false)}&lt;/li&gt;
-     * &lt;li&gt;{@code setQuote('&quot;')}&lt;/li&gt;
+     * &lt;li&gt;{@code setQuote(null)}&lt;/li&gt;
      * &lt;li&gt;{@code setRecordSeparator('\n')}&lt;/li&gt;
      * &lt;li&gt;{@code setNullString(&quot;\\N&quot;)}&lt;/li&gt;
      * &lt;li&gt;{@code setQuoteMode(QuoteMode.ALL_NON_NULL)}&lt;/li&gt;
@@ -1092,15 +1126,15 @@ public final class CSVFormat implements
      * @since 1.5
      */
     // @formatter:off
-<span class="fc" id="L1095">    public static final CSVFormat POSTGRESQL_TEXT 
= DEFAULT.builder()</span>
-<span class="fc" id="L1096">            .setDelimiter(TAB)</span>
-<span class="fc" id="L1097">            .setEscape(BACKSLASH)</span>
-<span class="fc" id="L1098">            .setIgnoreEmptyLines(false)</span>
-<span class="fc" id="L1099">            .setQuote(DOUBLE_QUOTE_CHAR)</span>
-<span class="fc" id="L1100">            .setRecordSeparator(LF)</span>
-<span class="fc" id="L1101">            .setNullString(&quot;\\N&quot;)</span>
-<span class="fc" id="L1102">            
.setQuoteMode(QuoteMode.ALL_NON_NULL)</span>
-<span class="fc" id="L1103">            .build();</span>
+<span class="fc" id="L1129">    public static final CSVFormat POSTGRESQL_TEXT 
= DEFAULT.builder()</span>
+<span class="fc" id="L1130">            .setDelimiter(TAB)</span>
+<span class="fc" id="L1131">            .setEscape(BACKSLASH)</span>
+<span class="fc" id="L1132">            .setIgnoreEmptyLines(false)</span>
+<span class="fc" id="L1133">            .setQuote(null)</span>
+<span class="fc" id="L1134">            .setRecordSeparator(LF)</span>
+<span class="fc" id="L1135">            
.setNullString(Constants.SQL_NULL_STRING)</span>
+<span class="fc" id="L1136">            
.setQuoteMode(QuoteMode.ALL_NON_NULL)</span>
+<span class="fc" id="L1137">            .build();</span>
     // @formatter:off
 
     /**
@@ -1118,9 +1152,9 @@ public final class CSVFormat implements
      *
      * @see Predefined#RFC4180
      */
-<span class="fc" id="L1121">    public static final CSVFormat RFC4180 = 
DEFAULT.builder().setIgnoreEmptyLines(false).build();</span>
+<span class="fc" id="L1155">    public static final CSVFormat RFC4180 = 
DEFAULT.builder().setIgnoreEmptyLines(false).build();</span>
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
 
     /**
      * Tab-delimited format.
@@ -1138,10 +1172,10 @@ public final class CSVFormat implements
      * @see Predefined#TDF
      */
     // @formatter:off
-<span class="fc" id="L1141">    public static final CSVFormat TDF = 
DEFAULT.builder()</span>
-<span class="fc" id="L1142">            .setDelimiter(TAB)</span>
-<span class="fc" id="L1143">            
.setIgnoreSurroundingSpaces(true)</span>
-<span class="fc" id="L1144">            .build();</span>
+<span class="fc" id="L1175">    public static final CSVFormat TDF = 
DEFAULT.builder()</span>
+<span class="fc" id="L1176">            .setDelimiter(TAB)</span>
+<span class="fc" id="L1177">            
.setIgnoreSurroundingSpaces(true)</span>
+<span class="fc" id="L1178">            .build();</span>
     // @formatter:on
 
     /**
@@ -1153,18 +1187,19 @@ public final class CSVFormat implements
      */
     @SafeVarargs
     static &lt;T&gt; T[] clone(final T... values) {
-<span class="fc bfc" id="L1156" title="All 2 branches covered.">        return 
values == null ? null : values.clone();</span>
+<span class="fc bfc" id="L1190" title="All 2 branches covered.">        return 
values == null ? null : values.clone();</span>
     }
 
     /**
      * Returns true if the given string contains the search char.
      *
      * @param source the string to check.
+     * @param searchCh the character to search.
      *
      * @return true if {@code c} contains a line break character
      */
     private static boolean contains(final String source, final char searchCh) {
-<span class="fc bfc" id="L1167" title="All 2 branches covered.">        return 
Objects.requireNonNull(source, &quot;source&quot;).indexOf(searchCh) &gt;= 
0;</span>
+<span class="fc bfc" id="L1202" title="All 2 branches covered.">        return 
Objects.requireNonNull(source, &quot;source&quot;).indexOf(searchCh) &gt;= 
0;</span>
     }
 
     /**
@@ -1175,7 +1210,11 @@ public final class CSVFormat implements
      * @return true if {@code c} contains a line break character.
      */
     private static boolean containsLineBreak(final String source) {
-<span class="fc bfc" id="L1178" title="All 4 branches covered.">        return 
contains(source, CR) || contains(source, LF);</span>
+<span class="fc bfc" id="L1213" title="All 4 branches covered.">        return 
contains(source, CR) || contains(source, LF);</span>
+    }
+
+    static boolean isBlank(final String value) {
+<span class="fc bfc" id="L1217" title="All 4 branches covered.">        return 
value == null || value.trim().isEmpty();</span>
     }
 
     /**
@@ -1186,7 +1225,7 @@ public final class CSVFormat implements
      * @return true if {@code c} is a line break character.
      */
     private static boolean isLineBreak(final char c) {
-<span class="fc bfc" id="L1189" title="All 4 branches covered.">        return 
c == LF || c == CR;</span>
+<span class="fc bfc" id="L1228" title="All 4 branches covered.">        return 
c == LF || c == CR;</span>
     }
 
     /**
@@ -1197,7 +1236,17 @@ public final class CSVFormat implements
      * @return true if {@code c} is a line break character (and not null).
      */
     private static boolean isLineBreak(final Character c) {
-<span class="fc bfc" id="L1200" title="All 4 branches covered.">        return 
c != null &amp;&amp; isLineBreak(c.charValue());</span>
+<span class="fc bfc" id="L1239" title="All 4 branches covered.">        return 
c != null &amp;&amp; isLineBreak(c.charValue());</span>
+    }
+
+    /** Same test as in as {@link String#trim()}. */
+    private static boolean isTrimChar(final char ch) {
+<span class="fc bfc" id="L1244" title="All 2 branches covered.">        return 
ch &lt;= SP;</span>
+    }
+
+    /** Same test as in as {@link String#trim()}. */
+    private static boolean isTrimChar(final CharSequence charSequence, final 
int pos) {
+<span class="fc" id="L1249">        return 
isTrimChar(charSequence.charAt(pos));</span>
     }
 
     /**
@@ -1218,36 +1267,34 @@ public final class CSVFormat implements
      * @see #TDF
      */
     public static CSVFormat newFormat(final char delimiter) {
-<span class="fc" id="L1221">        return new 
CSVFormat(String.valueOf(delimiter), null, null, null, null, false, false, 
null, null, null, null, false, false, false, false, false, false,</span>
-                true);
+<span class="fc" id="L1270">        return new 
CSVFormat(String.valueOf(delimiter), null, null, null, null, false, false, 
null, null, null, null, false, false, false, false, false, false,</span>
+                DuplicateHeaderMode.ALLOW_ALL);
     }
 
     static String[] toStringArray(final Object[] values) {
-<span class="fc bfc" id="L1226" title="All 2 branches covered.">        if 
(values == null) {</span>
-<span class="fc" id="L1227">            return null;</span>
-        }
-<span class="fc" id="L1229">        final String[] strings = new 
String[values.length];</span>
-<span class="fc bfc" id="L1230" title="All 2 branches covered.">        for 
(int i = 0; i &lt; values.length; i++) {</span>
-<span class="fc" id="L1231">            strings[i] = 
Objects.toString(values[i], null);</span>
+<span class="fc bfc" id="L1275" title="All 2 branches covered.">        if 
(values == null) {</span>
+<span class="fc" id="L1276">            return null;</span>
         }
-<span class="fc" id="L1233">        return strings;</span>
+<span class="fc" id="L1278">        final String[] strings = new 
String[values.length];</span>
+<span class="fc" id="L1279">        Arrays.setAll(strings, i -&gt; 
Objects.toString(values[i], null));</span>
+<span class="fc" id="L1280">        return strings;</span>
     }
 
     static CharSequence trim(final CharSequence charSequence) {
-<span class="fc bfc" id="L1237" title="All 2 branches covered.">        if 
(charSequence instanceof String) {</span>
-<span class="fc" id="L1238">            return ((String) 
charSequence).trim();</span>
+<span class="fc bfc" id="L1284" title="All 2 branches covered.">        if 
(charSequence instanceof String) {</span>
+<span class="fc" id="L1285">            return ((String) 
charSequence).trim();</span>
         }
-<span class="fc" id="L1240">        final int count = 
charSequence.length();</span>
-<span class="fc" id="L1241">        int len = count;</span>
-<span class="fc" id="L1242">        int pos = 0;</span>
+<span class="fc" id="L1287">        final int count = 
charSequence.length();</span>
+<span class="fc" id="L1288">        int len = count;</span>
+<span class="fc" id="L1289">        int pos = 0;</span>
 
-<span class="fc bfc" id="L1244" title="All 4 branches covered.">        while 
(pos &lt; len &amp;&amp; charSequence.charAt(pos) &lt;= SP) {</span>
-<span class="fc" id="L1245">            pos++;</span>
+<span class="fc bfc" id="L1291" title="All 4 branches covered.">        while 
(pos &lt; len &amp;&amp; isTrimChar(charSequence, pos)) {</span>
+<span class="fc" id="L1292">            pos++;</span>
         }
-<span class="fc bfc" id="L1247" title="All 4 branches covered.">        while 
(pos &lt; len &amp;&amp; charSequence.charAt(len - 1) &lt;= SP) {</span>
-<span class="fc" id="L1248">            len--;</span>
+<span class="fc bfc" id="L1294" title="All 4 branches covered.">        while 
(pos &lt; len &amp;&amp; isTrimChar(charSequence, len - 1)) {</span>
+<span class="fc" id="L1295">            len--;</span>
         }
-<span class="fc bfc" id="L1250" title="All 4 branches covered.">        return 
pos &gt; 0 || len &lt; count ? charSequence.subSequence(pos, len) : 
charSequence;</span>
+<span class="fc bfc" id="L1297" title="All 4 branches covered.">        return 
pos &gt; 0 || len &lt; count ? charSequence.subSequence(pos, len) : 
charSequence;</span>
     }
 
     /**
@@ -1258,10 +1305,10 @@ public final class CSVFormat implements
      * @since 1.2
      */
     public static CSVFormat valueOf(final String format) {
-<span class="fc" id="L1261">        return 
CSVFormat.Predefined.valueOf(format).getFormat();</span>
+<span class="fc" id="L1308">        return 
CSVFormat.Predefined.valueOf(format).getFormat();</span>
     }
 
-    private final boolean allowDuplicateHeaderNames;
+    private final DuplicateHeaderMode duplicateHeaderMode;
 
     private final boolean allowMissingColumnNames;
 
@@ -1273,7 +1320,7 @@ public final class CSVFormat implements
 
     private final Character escapeCharacter; // null if escaping is disabled
 
-    private final String[] header; // array of header column names
+    private final String[] headers; // array of header column names
 
     private final String[] headerComments; // array of header comment lines
 
@@ -1299,28 +1346,28 @@ public final class CSVFormat implements
 
     private final boolean trim;
 
-<span class="fc" id="L1302">    private CSVFormat(final Builder builder) 
{</span>
-<span class="fc" id="L1303">        this.delimiter = builder.delimiter;</span>
-<span class="fc" id="L1304">        this.quoteCharacter = 
builder.quoteCharacter;</span>
-<span class="fc" id="L1305">        this.quoteMode = builder.quoteMode;</span>
-<span class="fc" id="L1306">        this.commentMarker = 
builder.commentMarker;</span>
-<span class="fc" id="L1307">        this.escapeCharacter = 
builder.escapeCharacter;</span>
-<span class="fc" id="L1308">        this.ignoreSurroundingSpaces = 
builder.ignoreSurroundingSpaces;</span>
-<span class="fc" id="L1309">        this.allowMissingColumnNames = 
builder.allowMissingColumnNames;</span>
-<span class="fc" id="L1310">        this.ignoreEmptyLines = 
builder.ignoreEmptyLines;</span>
-<span class="fc" id="L1311">        this.recordSeparator = 
builder.recordSeparator;</span>
-<span class="fc" id="L1312">        this.nullString = 
builder.nullString;</span>
-<span class="fc" id="L1313">        this.headerComments = 
builder.headerComments;</span>
-<span class="fc" id="L1314">        this.header = builder.headers;</span>
-<span class="fc" id="L1315">        this.skipHeaderRecord = 
builder.skipHeaderRecord;</span>
-<span class="fc" id="L1316">        this.ignoreHeaderCase = 
builder.ignoreHeaderCase;</span>
-<span class="fc" id="L1317">        this.trailingDelimiter = 
builder.trailingDelimiter;</span>
-<span class="fc" id="L1318">        this.trim = builder.trim;</span>
-<span class="fc" id="L1319">        this.autoFlush = builder.autoFlush;</span>
-<span class="fc" id="L1320">        this.quotedNullString = 
builder.quotedNullString;</span>
-<span class="fc" id="L1321">        this.allowDuplicateHeaderNames = 
builder.allowDuplicateHeaderNames;</span>
-<span class="fc" id="L1322">        validate();</span>
-<span class="fc" id="L1323">    }</span>
+<span class="fc" id="L1349">    private CSVFormat(final Builder builder) 
{</span>
+<span class="fc" id="L1350">        this.delimiter = builder.delimiter;</span>
+<span class="fc" id="L1351">        this.quoteCharacter = 
builder.quoteCharacter;</span>
+<span class="fc" id="L1352">        this.quoteMode = builder.quoteMode;</span>
+<span class="fc" id="L1353">        this.commentMarker = 
builder.commentMarker;</span>
+<span class="fc" id="L1354">        this.escapeCharacter = 
builder.escapeCharacter;</span>
+<span class="fc" id="L1355">        this.ignoreSurroundingSpaces = 
builder.ignoreSurroundingSpaces;</span>
+<span class="fc" id="L1356">        this.allowMissingColumnNames = 
builder.allowMissingColumnNames;</span>
+<span class="fc" id="L1357">        this.ignoreEmptyLines = 
builder.ignoreEmptyLines;</span>
+<span class="fc" id="L1358">        this.recordSeparator = 
builder.recordSeparator;</span>
+<span class="fc" id="L1359">        this.nullString = 
builder.nullString;</span>
+<span class="fc" id="L1360">        this.headerComments = 
builder.headerComments;</span>
+<span class="fc" id="L1361">        this.headers = builder.headers;</span>
+<span class="fc" id="L1362">        this.skipHeaderRecord = 
builder.skipHeaderRecord;</span>
+<span class="fc" id="L1363">        this.ignoreHeaderCase = 
builder.ignoreHeaderCase;</span>
+<span class="fc" id="L1364">        this.trailingDelimiter = 
builder.trailingDelimiter;</span>
+<span class="fc" id="L1365">        this.trim = builder.trim;</span>
+<span class="fc" id="L1366">        this.autoFlush = builder.autoFlush;</span>
+<span class="fc" id="L1367">        this.quotedNullString = 
builder.quotedNullString;</span>
+<span class="fc" id="L1368">        this.duplicateHeaderMode = 
builder.duplicateHeaderMode;</span>
+<span class="fc" id="L1369">        validate();</span>
+<span class="fc" id="L1370">    }</span>
 
     /**
      * Creates a customized CSV format.
@@ -1342,50 +1389,51 @@ public final class CSVFormat implements
      * @param trim                    TODO Doc me.
      * @param trailingDelimiter       TODO Doc me.
      * @param autoFlush               TODO Doc me.
+     * @param duplicateHeaderMode     the behavior when handling duplicate 
headers
      * @throws IllegalArgumentException if the delimiter is a line break 
character.
      */
     private CSVFormat(final String delimiter, final Character quoteChar, final 
QuoteMode quoteMode, final Character commentStart, final Character escape,
             final boolean ignoreSurroundingSpaces, final boolean 
ignoreEmptyLines, final String recordSeparator, final String nullString,
             final Object[] headerComments, final String[] header, final 
boolean skipHeaderRecord, final boolean allowMissingColumnNames,
             final boolean ignoreHeaderCase, final boolean trim, final boolean 
trailingDelimiter, final boolean autoFlush,
-<span class="fc" id="L1351">            final boolean 
allowDuplicateHeaderNames) {</span>
-<span class="fc" id="L1352">        this.delimiter = delimiter;</span>
-<span class="fc" id="L1353">        this.quoteCharacter = quoteChar;</span>
-<span class="fc" id="L1354">        this.quoteMode = quoteMode;</span>
-<span class="fc" id="L1355">        this.commentMarker = commentStart;</span>
-<span class="fc" id="L1356">        this.escapeCharacter = escape;</span>
-<span class="fc" id="L1357">        this.ignoreSurroundingSpaces = 
ignoreSurroundingSpaces;</span>
-<span class="fc" id="L1358">        this.allowMissingColumnNames = 
allowMissingColumnNames;</span>
-<span class="fc" id="L1359">        this.ignoreEmptyLines = 
ignoreEmptyLines;</span>
-<span class="fc" id="L1360">        this.recordSeparator = 
recordSeparator;</span>
-<span class="fc" id="L1361">        this.nullString = nullString;</span>
-<span class="fc" id="L1362">        this.headerComments = 
toStringArray(headerComments);</span>
-<span class="fc" id="L1363">        this.header = clone(header);</span>
-<span class="fc" id="L1364">        this.skipHeaderRecord = 
skipHeaderRecord;</span>
-<span class="fc" id="L1365">        this.ignoreHeaderCase = 
ignoreHeaderCase;</span>
-<span class="fc" id="L1366">        this.trailingDelimiter = 
trailingDelimiter;</span>
-<span class="fc" id="L1367">        this.trim = trim;</span>
-<span class="fc" id="L1368">        this.autoFlush = autoFlush;</span>
-<span class="fc" id="L1369">        this.quotedNullString = quoteCharacter + 
nullString + quoteCharacter;</span>
-<span class="fc" id="L1370">        this.allowDuplicateHeaderNames = 
allowDuplicateHeaderNames;</span>
-<span class="fc" id="L1371">        validate();</span>
-<span class="fc" id="L1372">    }</span>
+<span class="fc" id="L1399">            final DuplicateHeaderMode 
duplicateHeaderMode) {</span>
+<span class="fc" id="L1400">        this.delimiter = delimiter;</span>
+<span class="fc" id="L1401">        this.quoteCharacter = quoteChar;</span>
+<span class="fc" id="L1402">        this.quoteMode = quoteMode;</span>
+<span class="fc" id="L1403">        this.commentMarker = commentStart;</span>
+<span class="fc" id="L1404">        this.escapeCharacter = escape;</span>
+<span class="fc" id="L1405">        this.ignoreSurroundingSpaces = 
ignoreSurroundingSpaces;</span>
+<span class="fc" id="L1406">        this.allowMissingColumnNames = 
allowMissingColumnNames;</span>
+<span class="fc" id="L1407">        this.ignoreEmptyLines = 
ignoreEmptyLines;</span>
+<span class="fc" id="L1408">        this.recordSeparator = 
recordSeparator;</span>
+<span class="fc" id="L1409">        this.nullString = nullString;</span>
+<span class="fc" id="L1410">        this.headerComments = 
toStringArray(headerComments);</span>
+<span class="fc" id="L1411">        this.headers = clone(header);</span>
+<span class="fc" id="L1412">        this.skipHeaderRecord = 
skipHeaderRecord;</span>
+<span class="fc" id="L1413">        this.ignoreHeaderCase = 
ignoreHeaderCase;</span>
+<span class="fc" id="L1414">        this.trailingDelimiter = 
trailingDelimiter;</span>
+<span class="fc" id="L1415">        this.trim = trim;</span>
+<span class="fc" id="L1416">        this.autoFlush = autoFlush;</span>
+<span class="fc" id="L1417">        this.quotedNullString = quoteCharacter + 
nullString + quoteCharacter;</span>
+<span class="fc" id="L1418">        this.duplicateHeaderMode = 
duplicateHeaderMode;</span>
+<span class="fc" id="L1419">        validate();</span>
+<span class="fc" id="L1420">    }</span>
 
     private void append(final char c, final Appendable appendable) throws 
IOException {
         //try {
-<span class="fc" id="L1376">            appendable.append(c);</span>
+<span class="fc" id="L1424">            appendable.append(c);</span>
         //} catch (final IOException e) {
         //    throw new UncheckedIOException(e);
         //}
-<span class="fc" id="L1380">    }</span>
+<span class="fc" id="L1428">    }</span>
 
     private void append(final CharSequence csq, final Appendable appendable) 
throws IOException {
         //try {
-<span class="fc" id="L1384">            appendable.append(csq);</span>
+<span class="fc" id="L1432">            appendable.append(csq);</span>
         //} catch (final IOException e) {
         //    throw new UncheckedIOException(e);
         //}
-<span class="fc" id="L1388">    }</span>
+<span class="fc" id="L1436">    }</span>
 
     /**
      * Creates a new Builder for this instance.
@@ -1393,7 +1441,7 @@ public final class CSVFormat implements
      * @return a new Builder.
      */
     public Builder builder() {
-<span class="fc" id="L1396">        return Builder.create(this);</span>
+<span class="fc" id="L1444">        return Builder.create(this);</span>
     }
 
     /**
@@ -1402,25 +1450,25 @@ public final class CSVFormat implements
      * @return a copy of this instance.
      */
     CSVFormat copy() {
-<span class="fc" id="L1405">        return builder().build();</span>
+<span class="fc" id="L1453">        return builder().build();</span>
     }
 
     @Override
     public boolean equals(final Object obj) {
-<span class="fc bfc" id="L1410" title="All 2 branches covered.">        if 
(this == obj) {</span>
-<span class="fc" id="L1411">            return true;</span>
+<span class="fc bfc" id="L1458" title="All 2 branches covered.">        if 
(this == obj) {</span>
+<span class="fc" id="L1459">            return true;</span>
         }
-<span class="pc bpc" id="L1413" title="2 of 4 branches missed.">        if 
(obj == null || getClass() != obj.getClass()) {</span>
-<span class="nc" id="L1414">            return false;</span>
+<span class="pc bpc" id="L1461" title="2 of 4 branches missed.">        if 
(obj == null || getClass() != obj.getClass()) {</span>
+<span class="nc" id="L1462">            return false;</span>
         }
-<span class="fc" id="L1416">        final CSVFormat other = (CSVFormat) 
obj;</span>
-<span class="fc bfc" id="L1417" title="All 6 branches covered.">        return 
allowDuplicateHeaderNames == other.allowDuplicateHeaderNames &amp;&amp; 
allowMissingColumnNames == other.allowMissingColumnNames &amp;&amp;</span>
-<span class="fc bfc" id="L1418" title="All 4 branches covered.">               
 autoFlush == other.autoFlush &amp;&amp; Objects.equals(commentMarker, 
other.commentMarker) &amp;&amp; Objects.equals(delimiter, other.delimiter) 
&amp;&amp;</span>
-<span class="fc bfc" id="L1419" title="All 4 branches covered.">               
 Objects.equals(escapeCharacter, other.escapeCharacter) &amp;&amp; 
Arrays.equals(header, other.header) &amp;&amp;</span>
-<span class="fc bfc" id="L1420" title="All 8 branches covered.">               
 Arrays.equals(headerComments, other.headerComments) &amp;&amp; 
ignoreEmptyLines == other.ignoreEmptyLines &amp;&amp;</span>
+<span class="fc" id="L1464">        final CSVFormat other = (CSVFormat) 
obj;</span>
+<span class="fc bfc" id="L1465" title="All 6 branches covered.">        return 
duplicateHeaderMode == other.duplicateHeaderMode &amp;&amp; 
allowMissingColumnNames == other.allowMissingColumnNames &amp;&amp;</span>
+<span class="fc bfc" id="L1466" title="All 4 branches covered.">               
 autoFlush == other.autoFlush &amp;&amp; Objects.equals(commentMarker, 
other.commentMarker) &amp;&amp; Objects.equals(delimiter, other.delimiter) 
&amp;&amp;</span>
+<span class="fc bfc" id="L1467" title="All 4 branches covered.">               
 Objects.equals(escapeCharacter, other.escapeCharacter) &amp;&amp; 
Arrays.equals(headers, other.headers) &amp;&amp;</span>
+<span class="fc bfc" id="L1468" title="All 8 branches covered.">               
 Arrays.equals(headerComments, other.headerComments) &amp;&amp; 
ignoreEmptyLines == other.ignoreEmptyLines &amp;&amp;</span>
                 ignoreHeaderCase == other.ignoreHeaderCase &amp;&amp; 
ignoreSurroundingSpaces == other.ignoreSurroundingSpaces &amp;&amp;
-<span class="fc bfc" id="L1422" title="All 6 branches covered.">               
 Objects.equals(nullString, other.nullString) &amp;&amp; 
Objects.equals(quoteCharacter, other.quoteCharacter) &amp;&amp; quoteMode == 
other.quoteMode &amp;&amp;</span>
-<span class="pc bpc" id="L1423" title="1 of 10 branches missed.">              
  Objects.equals(quotedNullString, other.quotedNullString) &amp;&amp; 
Objects.equals(recordSeparator, other.recordSeparator) &amp;&amp;</span>
+<span class="fc bfc" id="L1470" title="All 6 branches covered.">               
 Objects.equals(nullString, other.nullString) &amp;&amp; 
Objects.equals(quoteCharacter, other.quoteCharacter) &amp;&amp; quoteMode == 
other.quoteMode &amp;&amp;</span>
+<span class="pc bpc" id="L1471" title="1 of 10 branches missed.">              
  Objects.equals(quotedNullString, other.quotedNullString) &amp;&amp; 
Objects.equals(recordSeparator, other.recordSeparator) &amp;&amp;</span>
                 skipHeaderRecord == other.skipHeaderRecord &amp;&amp; 
trailingDelimiter == other.trailingDelimiter &amp;&amp; trim == other.trim;
     }
 
@@ -1431,129 +1479,142 @@ public final class CSVFormat implements
      * @return the formatted values
      */
     public String format(final Object... values) {
-<span class="fc" id="L1434">        final StringWriter out = new 
StringWriter();</span>
-<span class="fc" id="L1435">        try (CSVPrinter csvPrinter = new 
CSVPrinter(out, this)) {</span>
-<span class="fc" id="L1436">            csvPrinter.printRecord(values);</span>
-<span class="fc" id="L1437">            final String res = 
out.toString();</span>
-<span class="fc bfc" id="L1438" title="All 2 branches covered.">            
final int len = recordSeparator != null ? res.length() - 
recordSeparator.length() : res.length();</span>
-<span class="fc" id="L1439">            return res.substring(0, len);</span>
-<span class="nc" id="L1440">        } catch (final IOException e) {</span>
+<span class="fc" id="L1482">        final StringWriter out = new 
StringWriter();</span>
+<span class="fc" id="L1483">        try (CSVPrinter csvPrinter = new 
CSVPrinter(out, this)) {</span>
+<span class="fc" id="L1484">            csvPrinter.printRecord(values);</span>
+<span class="fc" id="L1485">            final String res = 
out.toString();</span>
+<span class="fc bfc" id="L1486" title="All 2 branches covered.">            
final int len = recordSeparator != null ? res.length() - 
recordSeparator.length() : res.length();</span>
+<span class="fc" id="L1487">            return res.substring(0, len);</span>
+<span class="nc" id="L1488">        } catch (final IOException e) {</span>
             // should not happen because a StringWriter does not do IO.
-<span class="nc" id="L1442">            throw new 
IllegalStateException(e);</span>
+<span class="nc" id="L1490">            throw new 
IllegalStateException(e);</span>
         }
     }
 
     /**
-     * Returns true if and only if duplicate names are allowed in the headers.
+     * Gets whether duplicate names are allowed in the headers.
      *
      * @return whether duplicate header names are allowed
      * @since 1.7
+     * @deprecated Use {@link #getDuplicateHeaderMode()}.
      */
+    @Deprecated
     public boolean getAllowDuplicateHeaderNames() {
-<span class="fc" id="L1453">        return allowDuplicateHeaderNames;</span>
+<span class="fc bfc" id="L1503" title="All 2 branches covered.">        return 
duplicateHeaderMode == DuplicateHeaderMode.ALLOW_ALL;</span>
     }
 
     /**
-     * Specifies whether missing column names are allowed when parsing the 
header line.
+     * Gets whether missing column names are allowed when parsing the header 
line.
      *
      * @return {@code true} if missing column names are allowed when parsing 
the header line, {@code false} to throw an {@link IllegalArgumentException}.
      */
     public boolean getAllowMissingColumnNames() {
-<span class="fc" id="L1462">        return allowMissingColumnNames;</span>
+<span class="fc" id="L1512">        return allowMissingColumnNames;</span>
     }
 
     /**
-     * Returns whether to flush on close.
+     * Gets whether to flush on close.
      *
      * @return whether to flush on close.
      * @since 1.6
      */
     public boolean getAutoFlush() {
-<span class="fc" id="L1472">        return autoFlush;</span>
+<span class="fc" id="L1522">        return autoFlush;</span>
     }
 
     /**
-     * Returns the character marking the start of a line comment.
+     * Gets the character marking the start of a line comment.
      *
      * @return the comment start marker, may be {@code null}
      */
     public Character getCommentMarker() {
-<span class="fc" id="L1481">        return commentMarker;</span>
+<span class="fc" id="L1531">        return commentMarker;</span>
     }
 
     /**
-     * Returns the first character delimiting the values (typically ';', ',' 
or '\t').
+     * Gets the first character delimiting the values (typically ';', ',' or 
'\t').
      *
      * @return the first delimiter character.
      * @deprecated Use {@link #getDelimiterString()}.
      */
     @Deprecated
     public char getDelimiter() {
-<span class="fc" id="L1492">        return delimiter.charAt(0);</span>
+<span class="fc" id="L1542">        return delimiter.charAt(0);</span>
     }
 
     /**
-     * Returns the character delimiting the values (typically &quot;;&quot;, 
&quot;,&quot; or &quot;\t&quot;).
+     * Gets the character delimiting the values (typically &quot;;&quot;, 
&quot;,&quot; or &quot;\t&quot;).
      *
      * @return the delimiter.
+     * @since 1.9.0
      */
     public String getDelimiterString() {
-<span class="fc" id="L1501">        return delimiter;</span>
+<span class="fc" id="L1552">        return delimiter;</span>
+    }
+
+    /**
+     * Gets how duplicate headers are handled.
+     *
+     * @return if duplicate header values are allowed, allowed conditionally, 
or disallowed.
+     * @since 1.10.0
+     */
+    public DuplicateHeaderMode getDuplicateHeaderMode() {
+<span class="fc" id="L1562">        return duplicateHeaderMode;</span>
     }
 
     /**
-     * Returns the escape character.
+     * Gets the escape character.
      *
      * @return the escape character, may be {@code null}
      */
     public Character getEscapeCharacter() {
-<span class="fc" id="L1510">        return escapeCharacter;</span>
+<span class="fc" id="L1571">        return escapeCharacter;</span>
     }
 
     /**
-     * Returns a copy of the header array.
+     * Gets a copy of the header array.
      *
      * @return a copy of the header array; {@code null} if disabled, the empty 
array if to be read from the file
      */
     public String[] getHeader() {
-<span class="fc bfc" id="L1519" title="All 2 branches covered.">        return 
header != null ? header.clone() : null;</span>
+<span class="fc bfc" id="L1580" title="All 2 branches covered.">        return 
headers != null ? headers.clone() : null;</span>
     }
 
     /**
-     * Returns a copy of the header comment array.
+     * Gets a copy of the header comment array.
      *
      * @return a copy of the header comment array; {@code null} if disabled.
      */
     public String[] getHeaderComments() {
-<span class="fc bfc" id="L1528" title="All 2 branches covered.">        return 
headerComments != null ? headerComments.clone() : null;</span>
+<span class="fc bfc" id="L1589" title="All 2 branches covered.">        return 
headerComments != null ? headerComments.clone() : null;</span>
     }
 
     /**
-     * Specifies whether empty lines between records are ignored when parsing 
input.
+     * Gets whether empty lines between records are ignored when parsing input.
      *
      * @return {@code true} if empty lines between records are ignored, {@code 
false} if they are turned into empty records.
      */
     public boolean getIgnoreEmptyLines() {
-<span class="fc" id="L1537">        return ignoreEmptyLines;</span>
+<span class="fc" id="L1598">        return ignoreEmptyLines;</span>
     }
 
     /**
-     * Specifies whether header names will be accessed ignoring case.
+     * Gets whether header names will be accessed ignoring case when parsing 
input.
      *
      * @return {@code true} if header names cases are ignored, {@code false} 
if they are case sensitive.
      * @since 1.3
      */
     public boolean getIgnoreHeaderCase() {
-<span class="fc" id="L1547">        return ignoreHeaderCase;</span>
+<span class="fc" id="L1608">        return ignoreHeaderCase;</span>
     }
 
     /**
-     * Specifies whether spaces around values are ignored when parsing input.
+     * Gets whether spaces around values are ignored when parsing input.
      *
      * @return {@code true} if spaces around values are ignored, {@code false} 
if they are treated as part of the value.
      */
     public boolean getIgnoreSurroundingSpaces() {
-<span class="fc" id="L1556">        return ignoreSurroundingSpaces;</span>
+<span class="fc" id="L1617">        return ignoreSurroundingSpaces;</span>
     }
 
     /**
@@ -1566,89 +1627,89 @@ public final class CSVFormat implements
      * @return the String to convert to and from {@code null}. No substitution 
occurs if {@code null}
      */
     public String getNullString() {
-<span class="fc" id="L1569">        return nullString;</span>
+<span class="fc" id="L1630">        return nullString;</span>
     }
 
     /**
-     * Returns the character used to encapsulate values containing special 
characters.
+     * Gets the character used to encapsulate values containing special 
characters.
      *
      * @return the quoteChar character, may be {@code null}
      */
     public Character getQuoteCharacter() {
-<span class="fc" id="L1578">        return quoteCharacter;</span>
+<span class="fc" id="L1639">        return quoteCharacter;</span>
     }
 
     /**
-     * Returns the quote policy output fields.
+     * Gets the quote policy output fields.
      *
      * @return the quote policy
      */
     public QuoteMode getQuoteMode() {
-<span class="fc" id="L1587">        return quoteMode;</span>
+<span class="fc" id="L1648">        return quoteMode;</span>
     }
 
     /**
-     * Returns the record separator delimiting output records.
+     * Gets the record separator delimiting output records.
      *
      * @return the record separator
      */
     public String getRecordSeparator() {
-<span class="fc" id="L1596">        return recordSeparator;</span>
+<span class="fc" id="L1657">        return recordSeparator;</span>
     }
 
     /**
-     * Returns whether to skip the header record.
+     * Gets whether to skip the header record.
      *
      * @return whether to skip the header record.
      */
     public boolean getSkipHeaderRecord() {
-<span class="fc" id="L1605">        return skipHeaderRecord;</span>
+<span class="fc" id="L1666">        return skipHeaderRecord;</span>
     }
 
     /**
-     * Returns whether to add a trailing delimiter.
+     * Gets whether to add a trailing delimiter.
      *
      * @return whether to add a trailing delimiter.
      * @since 1.3
      */
     public boolean getTrailingDelimiter() {
-<span class="fc" id="L1615">        return trailingDelimiter;</span>
+<span class="fc" id="L1676">        return trailingDelimiter;</span>
     }
 
     /**
-     * Returns whether to trim leading and trailing blanks. This is used by 
{@link #print(Object, Appendable, boolean)} Also by
+     * Gets whether to trim leading and trailing blanks. This is used by 
{@link #print(Object, Appendable, boolean)} Also by
      * {CSVParser#addRecordValue(boolean)}
      *
      * @return whether to trim leading and trailing blanks.
      */
     public boolean getTrim() {
-<span class="fc" id="L1625">        return trim;</span>
+<span class="fc" id="L1686">        return trim;</span>
     }
 
     @Override
     public int hashCode() {
-<span class="fc" id="L1630">        final int prime = 31;</span>
-<span class="fc" id="L1631">        int result = 1;</span>
-<span class="fc" id="L1632">        result = prime * result + 
Arrays.hashCode(header);</span>
-<span class="fc" id="L1633">        result = prime * result + 
Arrays.hashCode(headerComments);</span>
-<span class="fc" id="L1634">        return prime * result + 
Objects.hash(allowDuplicateHeaderNames, allowMissingColumnNames, autoFlush, 
commentMarker, delimiter, escapeCharacter,</span>
-<span class="fc" id="L1635">                ignoreEmptyLines, 
ignoreHeaderCase, ignoreSurroundingSpaces, nullString, quoteCharacter, 
quoteMode, quotedNullString, recordSeparator,</span>
-<span class="fc" id="L1636">                skipHeaderRecord, 
trailingDelimiter, trim);</span>
+<span class="fc" id="L1691">        final int prime = 31;</span>
+<span class="fc" id="L1692">        int result = 1;</span>
+<span class="fc" id="L1693">        result = prime * result + 
Arrays.hashCode(headers);</span>
+<span class="fc" id="L1694">        result = prime * result + 
Arrays.hashCode(headerComments);</span>
+<span class="fc" id="L1695">        return prime * result + 
Objects.hash(duplicateHeaderMode, allowMissingColumnNames, autoFlush, 
commentMarker, delimiter, escapeCharacter,</span>
+<span class="fc" id="L1696">                ignoreEmptyLines, 
ignoreHeaderCase, ignoreSurroundingSpaces, nullString, quoteCharacter, 
quoteMode, quotedNullString, recordSeparator,</span>
+<span class="fc" id="L1697">                skipHeaderRecord, 
trailingDelimiter, trim);</span>
     }
 
     /**
-     * Specifies whether comments are supported by this format.
+     * Tests whether comments are supported by this format.
      *
      * Note that the comment introducer character is only recognized at the 
start of a line.
      *
      * @return {@code true} is comments are supported, {@code false} otherwise
      */
     public boolean isCommentMarkerSet() {
-<span class="fc bfc" id="L1647" title="All 2 branches covered.">        return 
commentMarker != null;</span>
+<span class="fc bfc" id="L1708" title="All 2 branches covered.">        return 
commentMarker != null;</span>
     }
 
     /**
-     * Matches whether the next characters constitute a delimiter
+     * Tests whether the next characters constitute a delimiter
      *
      * @param ch
      *            the current char
@@ -1663,46 +1724,46 @@ public final class CSVFormat implements
      * @return true if the match is successful
      */
     private boolean isDelimiter(final char ch, final CharSequence charSeq, 
final int startIndex, final char[] delimiter, final int delimiterLength) {
-<span class="fc bfc" id="L1666" title="All 2 branches covered.">        if (ch 
!= delimiter[0]) {</span>
-<span class="fc" id="L1667">            return false;</span>
+<span class="fc bfc" id="L1727" title="All 2 branches covered.">        if (ch 
!= delimiter[0]) {</span>
+<span class="fc" id="L1728">            return false;</span>
         }
-<span class="fc" id="L1669">        final int len = charSeq.length();</span>
-<span class="fc bfc" id="L1670" title="All 2 branches covered.">        if 
(startIndex + delimiterLength &gt; len) {</span>
-<span class="fc" id="L1671">            return false;</span>
-        }
-<span class="fc bfc" id="L1673" title="All 2 branches covered.">        for 
(int i = 1; i &lt; delimiterLength; i++) {</span>
-<span class="fc bfc" id="L1674" title="All 2 branches covered.">            if 
(charSeq.charAt(startIndex + i) != delimiter[i]) {</span>
-<span class="fc" id="L1675">                return false;</span>
+<span class="fc" id="L1730">        final int len = charSeq.length();</span>
+<span class="fc bfc" id="L1731" title="All 2 branches covered.">        if 
(startIndex + delimiterLength &gt; len) {</span>
+<span class="fc" id="L1732">            return false;</span>
+        }
+<span class="fc bfc" id="L1734" title="All 2 branches covered.">        for 
(int i = 1; i &lt; delimiterLength; i++) {</span>
+<span class="fc bfc" id="L1735" title="All 2 branches covered.">            if 
(charSeq.charAt(startIndex + i) != delimiter[i]) {</span>
+<span class="fc" id="L1736">                return false;</span>
             }
         }
-<span class="fc" id="L1678">        return true;</span>
+<span class="fc" id="L1739">        return true;</span>
     }
 
     /**
-     * Returns whether escape are being processed.
+     * Tests whether escape are being processed.
      *
      * @return {@code true} if escapes are processed
      */
     public boolean isEscapeCharacterSet() {
-<span class="fc bfc" id="L1687" title="All 2 branches covered.">        return 
escapeCharacter != null;</span>
+<span class="fc bfc" id="L1748" title="All 2 branches covered.">        return 
escapeCharacter != null;</span>
     }
 
     /**
-     * Returns whether a nullString has been defined.
+     * Tests whether a nullString has been defined.
      *
      * @return {@code true} if a nullString is defined
      */
     public boolean isNullStringSet() {
-<span class="fc bfc" id="L1696" title="All 2 branches covered.">        return 
nullString != null;</span>
+<span class="fc bfc" id="L1757" title="All 2 branches covered.">        return 
nullString != null;</span>
     }
 
     /**
-     * Returns whether a quoteChar has been defined.
+     * Tests whether a quoteChar has been defined.
      *
      * @return {@code true} if a quoteChar is defined
      */
     public boolean isQuoteCharacterSet() {
-<span class="fc bfc" id="L1705" title="All 2 branches covered.">        return 
quoteCharacter != null;</span>
+<span class="fc bfc" id="L1766" title="All 2 branches covered.">        return 
quoteCharacter != null;</span>
     }
 
     /**
@@ -1717,7 +1778,7 @@ public final class CSVFormat implements
      * @throws IOException If an I/O error occurs
      */
     public CSVParser parse(final Reader reader) throws IOException {
-<span class="fc" id="L1720">        return new CSVParser(reader, this);</span>
+<span class="fc" id="L1781">        return new CSVParser(reader, this);</span>
     }
 
     /**
@@ -1732,7 +1793,7 @@ public final class CSVFormat implements
      * @throws IOException thrown if the optional header cannot be printed.
      */
     public CSVPrinter print(final Appendable out) throws IOException {
-<span class="fc" id="L1735">        return new CSVPrinter(out, this);</span>
+<span class="fc" id="L1796">        return new CSVPrinter(out, this);</span>
     }
 
     /**
@@ -1751,7 +1812,7 @@ public final class CSVFormat implements
     @SuppressWarnings(&quot;resource&quot;)
     public CSVPrinter print(final File out, final Charset charset) throws 
IOException {
         // The writer will be closed when close() is called.
-<span class="fc" id="L1754">        return new CSVPrinter(new 
OutputStreamWriter(new FileOutputStream(out), charset), this);</span>
+<span class="fc" id="L1815">        return new CSVPrinter(new 
OutputStreamWriter(new FileOutputStream(out), charset), this);</span>
     }
 
     /**
@@ -1764,48 +1825,48 @@ public final class CSVFormat implements
      * @throws IOException If an I/O error occurs.
      * @since 1.4
      */
-    public void print(final Object value, final Appendable out, final boolean 
newRecord) throws IOException {
+    public synchronized void print(final Object value, final Appendable out, 
final boolean newRecord) throws IOException {
         // null values are considered empty
         // Only call CharSequence.toString() if you have to, helps GC-free use 
cases.
         CharSequence charSequence;
-<span class="fc bfc" id="L1771" title="All 2 branches covered.">        if 
(value == null) {</span>
+<span class="fc bfc" id="L1832" title="All 2 branches covered.">        if 
(value == null) {</span>
             // https://issues.apache.org/jira/browse/CSV-203
-<span class="fc bfc" id="L1773" title="All 2 branches covered.">            if 
(null == nullString) {</span>
-<span class="fc" id="L1774">                charSequence = EMPTY;</span>
-<span class="fc bfc" id="L1775" title="All 2 branches covered.">            } 
else if (QuoteMode.ALL == quoteMode) {</span>
-<span class="fc" id="L1776">                charSequence = 
quotedNullString;</span>
+<span class="fc bfc" id="L1834" title="All 2 branches covered.">            if 
(null == nullString) {</span>
+<span class="fc" id="L1835">                charSequence = EMPTY;</span>
+<span class="fc bfc" id="L1836" title="All 2 branches covered.">            } 
else if (QuoteMode.ALL == quoteMode) {</span>
+<span class="fc" id="L1837">                charSequence = 
quotedNullString;</span>
             } else {
-<span class="fc" id="L1778">                charSequence = nullString;</span>
+<span class="fc" id="L1839">                charSequence = nullString;</span>
             }
-<span class="fc bfc" id="L1780" title="All 2 branches covered.">        } else 
if (value instanceof CharSequence) {</span>
-<span class="fc" id="L1781">            charSequence = (CharSequence) 
value;</span>
-<span class="fc bfc" id="L1782" title="All 2 branches covered.">        } else 
if (value instanceof Reader) {</span>

[... 1204 lines stripped ...]


Reply via email to