New Upstream Release - opencsv

Ready changes

Summary

Merged new upstream version: 5.3 (was: 5.2).

Resulting package

Built on 2022-05-11T04:53 (took 12m40s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases libopencsv-java

Lintian Result

Diff

diff --git a/debian/changelog b/debian/changelog
index 75f79f5..118e03f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+opencsv (5.3-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 11 May 2022 04:41:50 -0000
+
 opencsv (5.2-1) unstable; urgency=medium
 
   * New upstream release
diff --git a/pom.xml b/pom.xml
index 721ca33..3b649d2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
     <groupId>com.opencsv</groupId>
     <artifactId>opencsv</artifactId>
     <packaging>jar</packaging>
-    <version>5.2</version>
+    <version>5.2.1-SNAPSHOT</version>
     <name>opencsv</name>
     <description>A simple library for reading and writing CSV in Java</description>
     <url>http://opencsv.sf.net</url>
@@ -12,19 +12,18 @@
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <maven.surefire.version>2.22.2</maven.surefire.version>
-        <maven.site.version>3.9.0</maven.site.version>
-        <jacoco.version>0.8.5</jacoco.version>
+        <maven.site.version>3.9.1</maven.site.version>
+        <jacoco.version>0.8.6</jacoco.version>
         <maven.javadoc.version>3.2.0</maven.javadoc.version>
-        <maven-assembly-plugin.version>3.2.0</maven-assembly-plugin.version>
-        <commons-lang3.version>3.10</commons-lang3.version>
+        <maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
+        <commons-lang3.version>3.11</commons-lang3.version>
         <commons-collections4.version>4.4</commons-collections4.version>
         <argLine>-Dfile.encoding=UTF-8</argLine>
-        <junit.version>5.6.2</junit.version>
-        <junit-platform.version>1.3.2</junit-platform.version>
+        <junit.version>5.7.0</junit.version>
         <asciidoctor.maven.plugin.version>2.0.0-RC.1</asciidoctor.maven.plugin.version>
-        <asciidoctorj.version>2.2.0</asciidoctorj.version>
-        <jruby.version>9.2.11.0</jruby.version>
-        <asciidoctorj.diagram.version>2.0.1</asciidoctorj.diagram.version>
+        <asciidoctorj.version>2.3.0</asciidoctorj.version>
+        <jruby.version>9.2.11.1</jruby.version>
+        <asciidoctorj.diagram.version>2.0.2</asciidoctorj.diagram.version>
     </properties>
 
     <licenses>
@@ -237,7 +236,7 @@
                                     <pluginExecutionFilter>
                                         <groupId>org.codehaus.gmavenplus</groupId>
                                         <artifactId>gmavenplus-plugin</artifactId>
-                                        <versionRange>[1.8.1,)</versionRange>
+                                        <versionRange>[1.10.0,)</versionRange>
                                         <goals>
                                             <goal>addTestSources</goal>
                                             <goal>generateTestStubs</goal>
@@ -252,7 +251,7 @@
                                     <pluginExecutionFilter>
                                         <groupId>org.apache.felix</groupId>
                                         <artifactId>maven-bundle-plugin</artifactId>
-                                        <versionRange>[3.5.1,)</versionRange>
+                                        <versionRange>[5.1.1,)</versionRange>
                                         <goals>
                                             <goal>manifest</goal>
                                         </goals>
@@ -324,7 +323,7 @@
             <plugin>
                 <groupId>org.codehaus.gmavenplus</groupId>
                 <artifactId>gmavenplus-plugin</artifactId>
-                <version>1.9.0</version>
+                <version>1.10.0</version>
                 <configuration>
                     <testSources>
                         <testSource>
@@ -346,7 +345,7 @@
                     <dependency>
                         <groupId>org.codehaus.groovy</groupId>
                         <artifactId>groovy</artifactId>
-                        <version>3.0.0</version>
+                        <version>3.0.5</version>
                         <exclusions>
                             <exclusion>
                                 <artifactId>junit-dep</artifactId>
@@ -500,7 +499,7 @@
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <version>4.2.1</version>
+                <version>5.1.1</version>
                 <extensions>true</extensions>
                 <executions>
                     <execution>
@@ -537,7 +536,7 @@
             <extension>
                 <groupId>org.apache.maven.wagon</groupId>
                 <artifactId>wagon-ssh</artifactId>
-                <version>3.3.4</version>
+                <version>3.4.1</version>
             </extension>
         </extensions>
     </build>
@@ -556,7 +555,7 @@
             <dependency>
                 <groupId>junit</groupId>
                 <artifactId>junit</artifactId>
-                <version>4.13</version>
+                <version>4.13.1</version>
                 <scope>test</scope>
             </dependency>
             <dependency>
@@ -569,6 +568,12 @@
                 <artifactId>org.junit.platform</artifactId>
                 <version>${junit.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.hamcrest</groupId>
+                <artifactId>hamcrest-core</artifactId>
+                <version>2.2</version>
+                <scope>test</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
     <dependencies>
@@ -579,7 +584,7 @@
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-text</artifactId>
-            <version>1.8</version>
+            <version>1.9</version>
         </dependency>
         <dependency>
             <groupId>commons-beanutils</groupId>
@@ -594,13 +599,13 @@
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>3.3.3</version>
+            <version>3.5.11</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.spockframework</groupId>
             <artifactId>spock-core</artifactId>
-            <version>2.0-M2-groovy-3.0</version>
+            <version>2.0-M3-groovy-3.0</version>
             <scope>test</scope>
             <exclusions>
                 <exclusion>
@@ -650,7 +655,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-project-info-reports-plugin</artifactId>
-                <version>3.0.0</version>
+                <version>3.1.1</version>
                 <configuration>
                     <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
                 </configuration>
@@ -697,9 +702,9 @@
                 <version>${jacoco.version}</version>
             </plugin>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>findbugs-maven-plugin</artifactId>
-                <version>3.0.5</version>
+                <groupId>com.github.spotbugs</groupId>
+                <artifactId>spotbugs-maven-plugin</artifactId>
+                <version>4.0.4</version>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/src/main/java/com/opencsv/bean/AbstractBeanField.java b/src/main/java/com/opencsv/bean/AbstractBeanField.java
index 50349cd..2a0cacb 100644
--- a/src/main/java/com/opencsv/bean/AbstractBeanField.java
+++ b/src/main/java/com/opencsv/bean/AbstractBeanField.java
@@ -185,9 +185,7 @@ abstract public class AbstractBeanField<T, I> implements BeanField<T, I> {
     private String preProcessValue(PreAssignmentProcessor processor, String value) throws CsvValidationException {
         try {
             StringProcessor stringProcessor = processor.processor().newInstance();
-            if (Objects.nonNull(processor.paramString())) {
-                stringProcessor.setParameterString(processor.paramString());
-            }
+            stringProcessor.setParameterString(processor.paramString());
             return stringProcessor.processString(value);
         } catch (InstantiationException | IllegalAccessException e) {
             throw new CsvValidationException(String.format(
@@ -200,9 +198,7 @@ abstract public class AbstractBeanField<T, I> implements BeanField<T, I> {
     private void validateValue(PreAssignmentValidator validator, String value) throws CsvValidationException {
         try {
             StringValidator stringValidator = validator.validator().newInstance();
-            if (Objects.nonNull(validator.paramString())) {
-                stringValidator.setParameterString(validator.paramString());
-            }
+            stringValidator.setParameterString(validator.paramString());
             stringValidator.validate(value, this);
         } catch (InstantiationException | IllegalAccessException e) {
             throw new CsvValidationException(String.format(
@@ -364,8 +360,9 @@ abstract public class AbstractBeanField<T, I> implements BeanField<T, I> {
             // rather from write() using isFieldEmptyForWrite() to determine
             // when to throw the exception. But user code is still allowed
             // to override convertToWrite() and throw this exception
+            Class<?> beanClass = bean == null ? null : bean.getClass();
             CsvRequiredFieldEmptyException csve = new CsvRequiredFieldEmptyException(
-                    bean.getClass(), field, e.getMessage());
+                    beanClass, field, e.getMessage());
             csve.initCause(e.getCause());
             throw csve;
         }
diff --git a/src/main/java/com/opencsv/bean/AbstractMappingStrategy.java b/src/main/java/com/opencsv/bean/AbstractMappingStrategy.java
index 90e5657..a1ec9c2 100644
--- a/src/main/java/com/opencsv/bean/AbstractMappingStrategy.java
+++ b/src/main/java/com/opencsv/bean/AbstractMappingStrategy.java
@@ -308,7 +308,7 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
     }
 
     /**
-     * Get the class type that the Strategy is mapping.
+     * Get the class type that the strategy is mapping.
      *
      * @return Class of the object that this {@link MappingStrategy} will create.
      */
@@ -319,13 +319,29 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
     @SuppressWarnings("unchecked")
     @Override
     public T populateNewBean(String[] line)
-            throws CsvBeanIntrospectionException, CsvRequiredFieldEmptyException,
-            CsvDataTypeMismatchException, CsvConstraintViolationException,
-            CsvValidationException {
+            throws CsvBeanIntrospectionException, CsvFieldAssignmentException,
+            CsvChainedException {
         verifyLineLength(line.length);
         Map<Class<?>, Object> beanTree = createBean();
+
+        CsvChainedException chainedException = null;
         for (int col = 0; col < line.length; col++) {
-            setFieldValue(beanTree, line[col], col);
+            try {
+                setFieldValue(beanTree, line[col], col);
+            } catch (CsvFieldAssignmentException e) {
+                if(chainedException != null) {
+                    chainedException.add(e);
+                }
+                else {
+                    chainedException = new CsvChainedException(e);
+                }
+            }
+        }
+        if(chainedException != null) {
+            if (chainedException.hasOnlyOneException()) {
+                throw chainedException.getFirstException();
+            }
+            throw chainedException;
         }
         return (T)beanTree.get(type);
     }
@@ -379,7 +395,7 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
      * @param fields The fields to be filtered
      * @return A list of fields that exist for opencsv
      */
-    private List<Field> filterIgnoredFields(final Class<?> type, Field[] fields) {
+    protected List<Field> filterIgnoredFields(final Class<?> type, Field[] fields) {
         return Stream.of(fields)
                 .filter(f -> !ignoredFields.containsMapping(type, f) && !f.isAnnotationPresent(CsvIgnore.class))
                 .collect(Collectors.toList());
@@ -409,6 +425,16 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
         }
     }
 
+    /**
+     * @param type Class to be checked
+     * @return Whether the type may be recursed into ({@code false}), or
+     *   must be considered a leaf node for recursion ({@code true}). This
+     *   implementation considers the boxed primitives forbidden.
+     */
+    protected boolean isForbiddenClassForRecursion(Class<?> type) {
+        return FORBIDDEN_CLASSES_FOR_RECURSION.contains(type);
+    }
+
     /**
      * Creates a tree of beans embedded in each other.
      * These are the member variables annotated with {@link CsvRecurse} and
@@ -428,7 +454,7 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
     protected RecursiveType loadRecursiveClasses(Class<?> newType, Set<Class<?>> encounteredTypes) {
 
         // We cannot recurse into primitive types
-        if (FORBIDDEN_CLASSES_FOR_RECURSION.contains(newType)) {
+        if (isForbiddenClassForRecursion(newType)) {
             throw new CsvRecursionException(
                     ResourceBundle.getBundle(
                             ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale)
@@ -583,7 +609,7 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
     }
     
     @Override
-    public String[] transmuteBean(T bean) throws CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
+    public String[] transmuteBean(T bean) throws CsvFieldAssignmentException, CsvChainedException {
         int numColumns = headerIndex.findMaxIndex()+1;
         BeanField<T, K> firstBeanField, subsequentBeanField;
         K firstIndex, subsequentIndex;
@@ -606,15 +632,26 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
             throw csve;
         }
 
-
+        CsvChainedException chainedException = null;
         for(int i = 0; i < numColumns;) {
 
             // Determine the first value
             firstBeanField = findField(i);
             firstIndex = chooseMultivaluedFieldIndexFromHeaderIndex(i);
-            String[] fields = firstBeanField != null
-                    ? firstBeanField.write(instanceMap.get(firstBeanField.getType()), firstIndex)
-                    : ArrayUtils.EMPTY_STRING_ARRAY;
+            String[] fields = ArrayUtils.EMPTY_STRING_ARRAY;
+            if(firstBeanField != null) {
+                try {
+                    fields = firstBeanField.write(instanceMap.get(firstBeanField.getType()), firstIndex);
+                }
+                catch(CsvDataTypeMismatchException | CsvRequiredFieldEmptyException e) {
+                    if(chainedException != null) {
+                        chainedException.add(e);
+                    }
+                    else {
+                        chainedException = new CsvChainedException(e);
+                    }
+                }
+            }
 
             if(fields.length == 0) {
 
@@ -664,6 +701,15 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
                 }
             }
         }
+
+        // If there were exceptions, throw them
+        if(chainedException != null) {
+            if (chainedException.hasOnlyOneException()) {
+                throw chainedException.getFirstException();
+            }
+            throw chainedException;
+        }
+
         return contents.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
     }
 
@@ -684,13 +730,13 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
      * @since 4.2
      */
     protected CsvConverter determineConverter(Field field,
-            Class<?> elementType, String locale, String writeLocale,
-            Class<? extends AbstractCsvConverter> customConverter)
+                                              Class<?> elementType, String locale, String writeLocale,
+                                              Class<? extends AbstractCsvConverter> customConverter)
             throws CsvBadConverterException {
         CsvConverter converter;
 
         // A custom converter always takes precedence if specified.
-        if(customConverter != null && !customConverter.equals(AbstractCsvConverter.class)) {
+        if (customConverter != null && !customConverter.equals(AbstractCsvConverter.class)) {
             try {
                 converter = customConverter.newInstance();
             } catch (IllegalAccessException | InstantiationException oldEx) {
@@ -729,17 +775,21 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
                     errorLocale, readFormat, writeFormat);
         }
 
-        // Otherwise it must be a primitive or enumeration
+        // or a Currency
+        else if (elementType.equals(java.util.Currency.class)){
+            converter = new ConverterCurrency(errorLocale);
+        }
+
+        // Or an enumeration
+        else if(elementType.isEnum()) {
+            converter = new ConverterEnum(elementType, locale, writeLocale, errorLocale);
+        }
+
+        // Otherwise a primitive
         else {
-            if(elementType.isEnum()) {
-                converter = new ConverterEnum(
-                        elementType, locale, writeLocale, errorLocale);
-            }
-            else {
-                converter = new ConverterPrimitiveTypes(
-                        elementType, locale, writeLocale, errorLocale);
-            }
+            converter = new ConverterPrimitiveTypes(elementType, locale, writeLocale, errorLocale);
         }
+
         return converter;
     }
 
@@ -747,20 +797,41 @@ abstract public class AbstractMappingStrategy<I, K extends Comparable<K>, C exte
      * Encapsulates a bean type and all of the member variables that need to be
      * recursed into.
      */
-    private static class RecursiveType {
+    protected static class RecursiveType {
         private final Class<?> type;
         private final Map<FieldAccess<Object>, RecursiveType> recursiveMembers = new HashMap<>();
 
+        /**
+         * Constructs a {@link RecursiveType} with the specified type.
+         *
+         * @param type Type associated with this branch
+         */
         RecursiveType(Class<?> type) {
             this.type = type;
         }
 
-        public Class<?> getType() {return type;}
+        /**
+         * @return Type associated with this branch
+         */
+        public Class<?> getType() {
+            return type;
+        }
 
-        public RecursiveType addRecursiveMember(FieldAccess<Object> member, RecursiveType memberType) {
-            return recursiveMembers.put(member, memberType);
+        /**
+         * Used to add a recursive type.
+         *
+         * @param member     Field access member to add a recursive type to
+         * @param memberType {@link RecursiveType} to add
+         */
+        public void addRecursiveMember(FieldAccess<Object> member, RecursiveType memberType) {
+            recursiveMembers.put(member, memberType);
         }
 
-        public Map<FieldAccess<Object>, RecursiveType> getRecursiveMembers() {return recursiveMembers;}
+        /**
+         * @return {@link Map} of field access to {@link RecursiveType}.
+         */
+        public Map<FieldAccess<Object>, RecursiveType> getRecursiveMembers() {
+            return recursiveMembers;
+        }
     }
 }
diff --git a/src/main/java/com/opencsv/bean/ColumnPositionMappingStrategy.java b/src/main/java/com/opencsv/bean/ColumnPositionMappingStrategy.java
index fa38071..d673dde 100644
--- a/src/main/java/com/opencsv/bean/ColumnPositionMappingStrategy.java
+++ b/src/main/java/com/opencsv/bean/ColumnPositionMappingStrategy.java
@@ -6,7 +6,6 @@ import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
 import org.apache.commons.collections4.ListValuedMap;
 import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.ObjectUtils;
 
 import java.io.IOException;
 import java.lang.annotation.Annotation;
@@ -70,7 +69,7 @@ public class ColumnPositionMappingStrategy<T> extends AbstractMappingStrategy<St
                     .getString("type.unset"));
         }
 
-        String[] firstLine = ObjectUtils.defaultIfNull(reader.peek(), ArrayUtils.EMPTY_STRING_ARRAY);
+        String[] firstLine = ArrayUtils.nullToEmpty(reader.peek());
         fieldMap.setMaxIndex(firstLine.length - 1);
         if (!columnsExplicitlySet) {
             headerIndex.clear();
diff --git a/src/main/java/com/opencsv/bean/ConverterCurrency.java b/src/main/java/com/opencsv/bean/ConverterCurrency.java
new file mode 100644
index 0000000..b3e3a33
--- /dev/null
+++ b/src/main/java/com/opencsv/bean/ConverterCurrency.java
@@ -0,0 +1,66 @@
+package com.opencsv.bean;
+
+import com.opencsv.ICSVParser;
+import com.opencsv.exceptions.CsvDataTypeMismatchException;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Currency;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * This class converts an input ISO 4217 currency code to a {@link java.util.Currency}
+ * instance.
+ *
+ * @author Andrew Munn
+ * @since 5.3
+ */
+public class ConverterCurrency extends AbstractCsvConverter {
+
+    /**
+     * Initializes the class.
+     * @param errorLocale     The locale to use for error messages
+     */
+    public ConverterCurrency(Locale errorLocale) {
+        super(Currency.class, null, null, errorLocale);
+    }
+
+    /**
+     * @param value The ISO 4217 currency code string to be converted
+     * @return {@link java.util.Currency} instance
+     */
+    @Override
+    public Object convertToRead(String value) throws CsvDataTypeMismatchException {
+        Currency c = null;
+        if (StringUtils.isNotEmpty(value)) {
+            try {
+                c = Currency.getInstance(value);
+            } catch (IllegalArgumentException e) {
+                CsvDataTypeMismatchException csve = new CsvDataTypeMismatchException(value, type, String.format(
+                        ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME).getString("invalid.currency.value"),
+                        value, type.getName()));
+                csve.initCause(e);
+                throw csve;
+            }
+
+        }
+        return c;
+    }
+
+    /**
+     * Converts {@link java.util.Currency} instance to a string.
+     *
+     * @param value The {@link java.util.Currency} instance
+     * @return ISO 4217 currency code or {@code null} if value was {@code null}
+     * @throws CsvDataTypeMismatchException If the value is not a {@link java.util.Currency}
+     */
+    @Override
+    public String convertToWrite(Object value) throws CsvDataTypeMismatchException {
+        String result = null;
+        if (value != null) {
+            Currency c = (Currency) value;
+            result = c.getCurrencyCode();
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/opencsv/bean/HeaderNameBaseMappingStrategy.java b/src/main/java/com/opencsv/bean/HeaderNameBaseMappingStrategy.java
index 95d1c41..2c48022 100644
--- a/src/main/java/com/opencsv/bean/HeaderNameBaseMappingStrategy.java
+++ b/src/main/java/com/opencsv/bean/HeaderNameBaseMappingStrategy.java
@@ -6,7 +6,7 @@ import com.opencsv.exceptions.CsvBadConverterException;
 import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
 import org.apache.commons.collections4.ListValuedMap;
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.io.IOException;
 import java.io.Serializable;
@@ -42,7 +42,14 @@ abstract public class HeaderNameBaseMappingStrategy<T> extends AbstractMappingSt
         }
 
         // Read the header
-        String[] header = ObjectUtils.defaultIfNull(reader.readNextSilently(), ArrayUtils.EMPTY_STRING_ARRAY);
+        String[] header = ArrayUtils.nullToEmpty(reader.readNextSilently());
+        for(int i = 0; i < header.length; i++) {
+            // For the case that a header is empty and someone configured
+            // empty fields to be null
+            if(header[i] == null) {
+                header[i] = StringUtils.EMPTY;
+            }
+        }
         headerIndex.initializeHeaderIndex(header);
 
         // Throw an exception if any required headers are missing
diff --git a/src/main/java/com/opencsv/bean/MappingStrategy.java b/src/main/java/com/opencsv/bean/MappingStrategy.java
index bb1bcb2..4f596c6 100644
--- a/src/main/java/com/opencsv/bean/MappingStrategy.java
+++ b/src/main/java/com/opencsv/bean/MappingStrategy.java
@@ -85,21 +85,16 @@ public interface MappingStrategy<T> {
      * @return A bean containing the converted information from the input
      * @throws CsvBeanIntrospectionException Generally, if some part of the bean cannot
      *   be accessed and used as needed
-     * @throws CsvRequiredFieldEmptyException If the input for a field defined
-     *   as required is empty
-     * @throws CsvDataTypeMismatchException If conversion of the input to a
-     *   field type fails
-     * @throws CsvConstraintViolationException If the value provided for a field
-     *   would in some way compromise the logical integrity of the data as a
-     *   whole
-     * @throws CsvValidationException If a user-supplied validator determines
-     * that the input is invalid
+     * @throws CsvFieldAssignmentException A more specific subclass of this
+     *   exception is thrown for any problem decoding and assigning a field
+     *   of the input to a bean field
+     * @throws CsvChainedException If multiple exceptions are thrown for the
+     * same input line
      * @since 4.2
      */
     T populateNewBean(String[] line)
-            throws CsvBeanIntrospectionException, CsvRequiredFieldEmptyException,
-            CsvDataTypeMismatchException, CsvConstraintViolationException,
-            CsvValidationException;
+            throws CsvBeanIntrospectionException, CsvFieldAssignmentException,
+            CsvChainedException;
     
     /**
      * Sets the locale for all error messages.
@@ -170,10 +165,11 @@ public interface MappingStrategy<T> {
      * @param bean The bean to be transmuted
      * @return The converted values of the bean fields in the correct order,
      *   ready to be passed to a {@link com.opencsv.CSVWriter}
-     * @throws CsvDataTypeMismatchException If expected to convert an
-     *   unsupported data type
-     * @throws CsvRequiredFieldEmptyException If the field is marked as required,
-     *   but is currently empty
+     * @throws CsvFieldAssignmentException A more specific subclass of this
+     *   exception is thrown for any problem decoding and assigning a field
+     *   of the input to a bean field
+     * @throws CsvChainedException If multiple exceptions are thrown for the
+     * same input line
      */
-    String[] transmuteBean(T bean) throws CsvDataTypeMismatchException, CsvRequiredFieldEmptyException;
+    String[] transmuteBean(T bean) throws CsvFieldAssignmentException, CsvChainedException;
 }
\ No newline at end of file
diff --git a/src/main/java/com/opencsv/bean/StatefulBeanToCsv.java b/src/main/java/com/opencsv/bean/StatefulBeanToCsv.java
index 7a8ab06..d892850 100644
--- a/src/main/java/com/opencsv/bean/StatefulBeanToCsv.java
+++ b/src/main/java/com/opencsv/bean/StatefulBeanToCsv.java
@@ -19,11 +19,11 @@ import com.opencsv.CSVWriter;
 import com.opencsv.ICSVParser;
 import com.opencsv.ICSVWriter;
 import com.opencsv.bean.concurrent.BeanExecutor;
-import com.opencsv.bean.util.OrderedObject;
 import com.opencsv.bean.concurrent.ProcessCsvBean;
 import com.opencsv.bean.exceptionhandler.CsvExceptionHandler;
 import com.opencsv.bean.exceptionhandler.ExceptionHandlerThrow;
 import com.opencsv.bean.util.OpencsvUtils;
+import com.opencsv.bean.util.OrderedObject;
 import com.opencsv.exceptions.CsvDataTypeMismatchException;
 import com.opencsv.exceptions.CsvException;
 import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
@@ -383,6 +383,7 @@ public class StatefulBeanToCsv<T> {
     public List<CsvException> getCapturedExceptions() {
         List<CsvException> intermediate = capturedExceptions;
         capturedExceptions = new ArrayList<>();
+        intermediate.sort(Comparator.comparingLong(CsvException::getLineNumber));
         return intermediate;
     }
 
diff --git a/src/main/java/com/opencsv/bean/concurrent/AccumulateCsvResults.java b/src/main/java/com/opencsv/bean/concurrent/AccumulateCsvResults.java
index 1e780f8..fd38f76 100644
--- a/src/main/java/com/opencsv/bean/concurrent/AccumulateCsvResults.java
+++ b/src/main/java/com/opencsv/bean/concurrent/AccumulateCsvResults.java
@@ -17,6 +17,7 @@ package com.opencsv.bean.concurrent;
 
 import com.opencsv.bean.util.OrderedObject;
 import com.opencsv.exceptions.CsvException;
+import org.apache.commons.collections4.ListValuedMap;
 
 import java.util.SortedSet;
 import java.util.concurrent.BlockingQueue;
@@ -39,9 +40,11 @@ class AccumulateCsvResults<T> extends Thread {
     private final BlockingQueue<OrderedObject<CsvException>> thrownExceptionsQueue;
     private final SortedSet<Long> expectedRecords;
     private final ConcurrentMap<Long, T> resultantBeanMap;
-    private final ConcurrentMap<Long, CsvException> thrownExceptionsMap;
     private boolean mustStop = false;
 
+    /** <em>All access to this variable must be synchronized.</em> */
+    private final ListValuedMap<Long, CsvException> thrownExceptionsMap;
+
     /**
      * The only accepted constructor for the accumulator.
      * @param resultantBeansQueue A queue of beans coming out of the pool of
@@ -55,14 +58,15 @@ class AccumulateCsvResults<T> extends Thread {
      *                        while converting can be detected.
      * @param resultantBeanMap The (ordered) map of beans that have been
      *   created. The accumulator inserts into this map.
-     * @param thrownExceptionsMap The (ordered) map of suppressed exceptions
-     *   thrown during bean creation. The accumulator inserts into this map.
+     * @param thrownExceptionsMap The map of suppressed exceptions thrown
+     *   during bean creation. The accumulator inserts into this map. <em>All
+     *   access to this variable must be synchronized.</em>
      */
     AccumulateCsvResults(BlockingQueue<OrderedObject<T>> resultantBeansQueue,
                          BlockingQueue<OrderedObject<CsvException>> thrownExceptionsQueue,
                          SortedSet<Long> expectedRecords,
                          ConcurrentMap<Long, T> resultantBeanMap,
-                         ConcurrentMap<Long, CsvException> thrownExceptionsMap) {
+                         ListValuedMap<Long, CsvException> thrownExceptionsMap) {
         super();
         this.resultantBeansQueue = resultantBeansQueue;
         this.thrownExceptionsQueue = thrownExceptionsQueue;
@@ -123,7 +127,9 @@ class AccumulateCsvResults<T> extends Thread {
             while(!thrownExceptionsQueue.isEmpty()) {
                 OrderedObject<CsvException> capturedException = thrownExceptionsQueue.poll();
                 if(capturedException != null) {
-                    thrownExceptionsMap.put(capturedException.getOrdinal(), capturedException.getElement());
+                    synchronized (thrownExceptionsMap) {
+                        thrownExceptionsMap.put(capturedException.getOrdinal(), capturedException.getElement());
+                    }
                 }
             }
             Thread.yield();
diff --git a/src/main/java/com/opencsv/bean/concurrent/IntolerantThreadPoolExecutor.java b/src/main/java/com/opencsv/bean/concurrent/IntolerantThreadPoolExecutor.java
index 6dba817..bbdddd6 100644
--- a/src/main/java/com/opencsv/bean/concurrent/IntolerantThreadPoolExecutor.java
+++ b/src/main/java/com/opencsv/bean/concurrent/IntolerantThreadPoolExecutor.java
@@ -18,6 +18,8 @@ package com.opencsv.bean.concurrent;
 import com.opencsv.ICSVParser;
 import com.opencsv.bean.util.OrderedObject;
 import com.opencsv.exceptions.CsvException;
+import org.apache.commons.collections4.ListValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.ObjectUtils;
 
@@ -73,8 +75,13 @@ class IntolerantThreadPoolExecutor<T> extends ThreadPoolExecutor implements Spli
     /** A sorted, concurrent map for the beans created. */
     private ConcurrentNavigableMap<Long, T> resultantBeansMap = null;
 
-    /** A sorted, concurrent map for any exceptions captured. */
-    private ConcurrentNavigableMap<Long, CsvException> thrownExceptionsMap = null;
+    /**
+     * A multi-valued map for any exceptions captured.
+     * <p>The multi-valued part is important because the same line can throw more
+     * than one exception.</p>
+     * <p><em>All access to this variable must be synchronized.</em></p>
+     * */
+    private ListValuedMap<Long, CsvException> thrownExceptionsMap = null;
 
     /** A separate thread that accumulates and orders results. */
     protected AccumulateCsvResults<T> accumulateThread = null;
@@ -122,7 +129,7 @@ class IntolerantThreadPoolExecutor<T> extends ThreadPoolExecutor implements Spli
         // processing.
         if(orderedResults) {
             resultantBeansMap = new ConcurrentSkipListMap<>();
-            thrownExceptionsMap = new ConcurrentSkipListMap<>();
+            thrownExceptionsMap = new ArrayListValuedHashMap<>();
 
             // Start the process for accumulating results and cleaning up
             accumulateThread = new AccumulateCsvResults<>(
@@ -167,12 +174,23 @@ class IntolerantThreadPoolExecutor<T> extends ThreadPoolExecutor implements Spli
      * @return All exceptions captured
      */
     public List<CsvException> getCapturedExceptions() {
-        return thrownExceptionsMap == null ?
-                thrownExceptionsQueue.stream()
-                        .filter(Objects::nonNull)
-                        .map(OrderedObject::getElement)
-                        .collect(Collectors.toList()) :
-                new ArrayList<>(thrownExceptionsMap.values());
+        List<CsvException> returnList = null;
+        if(thrownExceptionsMap == null) {
+            returnList = thrownExceptionsQueue.stream()
+                    .filter(Objects::nonNull)
+                    .map(OrderedObject::getElement)
+                    .collect(Collectors.toList());
+        }
+        else {
+            returnList = new LinkedList<>();
+            synchronized (thrownExceptionsMap) {
+                final List<CsvException> finalReturnList = returnList;
+                thrownExceptionsMap.keySet().stream()
+                        .sorted()
+                        .forEach(l -> finalReturnList.addAll(thrownExceptionsMap.get(l)));
+            }
+        }
+        return returnList;
     }
 
     @Override
@@ -230,7 +248,7 @@ class IntolerantThreadPoolExecutor<T> extends ThreadPoolExecutor implements Spli
             if(terminalException instanceof CsvException) {
                 CsvException csve = (CsvException) terminalException;
                 throw new RuntimeException(String.format(ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("parsing.error.linenumber"),
-                        csve.getLineNumber(), String.join(",", ObjectUtils.defaultIfNull(csve.getLine(), ArrayUtils.EMPTY_STRING_ARRAY))), csve);
+                        csve.getLineNumber(), String.join(",", ArrayUtils.nullToEmpty(csve.getLine()))), csve);
             }
             throw new RuntimeException(terminalException);
         }
diff --git a/src/main/java/com/opencsv/bean/concurrent/ProcessCsvBean.java b/src/main/java/com/opencsv/bean/concurrent/ProcessCsvBean.java
index bc621dd..c2089e2 100644
--- a/src/main/java/com/opencsv/bean/concurrent/ProcessCsvBean.java
+++ b/src/main/java/com/opencsv/bean/concurrent/ProcessCsvBean.java
@@ -16,10 +16,13 @@
 package com.opencsv.bean.concurrent;
 
 import com.opencsv.bean.MappingStrategy;
-import com.opencsv.bean.util.OpencsvUtils;
 import com.opencsv.bean.exceptionhandler.CsvExceptionHandler;
+import com.opencsv.bean.util.OpencsvUtils;
 import com.opencsv.bean.util.OrderedObject;
-import com.opencsv.exceptions.*;
+import com.opencsv.exceptions.CsvChainedException;
+import com.opencsv.exceptions.CsvException;
+import com.opencsv.exceptions.CsvFieldAssignmentException;
+import com.opencsv.exceptions.CsvRuntimeException;
 
 import java.util.SortedSet;
 import java.util.concurrent.BlockingQueue;
@@ -74,7 +77,7 @@ public class ProcessCsvBean<T> implements Runnable {
             OpencsvUtils.queueRefuseToAcceptDefeat(resultantLineQueue,
                     new OrderedObject<>(lineNumber, mappingStrategy.transmuteBean(bean)));
         }
-        catch (CsvException e) {
+        catch (CsvFieldAssignmentException | CsvChainedException e) {
             expectedRecords.remove(lineNumber);
             OpencsvUtils.handleException(e, lineNumber, exceptionHandler, thrownExceptionsQueue);
         }
diff --git a/src/main/java/com/opencsv/bean/concurrent/ProcessCsvLine.java b/src/main/java/com/opencsv/bean/concurrent/ProcessCsvLine.java
index d53e0d2..467af0b 100644
--- a/src/main/java/com/opencsv/bean/concurrent/ProcessCsvLine.java
+++ b/src/main/java/com/opencsv/bean/concurrent/ProcessCsvLine.java
@@ -18,8 +18,8 @@ package com.opencsv.bean.concurrent;
 import com.opencsv.bean.BeanVerifier;
 import com.opencsv.bean.CsvToBeanFilter;
 import com.opencsv.bean.MappingStrategy;
-import com.opencsv.bean.util.OpencsvUtils;
 import com.opencsv.bean.exceptionhandler.CsvExceptionHandler;
+import com.opencsv.bean.util.OpencsvUtils;
 import com.opencsv.bean.util.OrderedObject;
 import com.opencsv.exceptions.*;
 import org.apache.commons.lang3.ArrayUtils;
@@ -118,20 +118,16 @@ public class ProcessCsvLine<T> implements Runnable {
      * @throws CsvBeanIntrospectionException Thrown on error creating bean.
      * @throws CsvBadConverterException If a custom converter cannot be
      *   initialized properly
-     * @throws CsvDataTypeMismatchException If the source data cannot be
-     *   converted to the type of the destination field
-     * @throws CsvRequiredFieldEmptyException If a mandatory field is empty in
-     *   the input file
-     * @throws CsvConstraintViolationException When the internal structure of
-     *   data would be violated by the data in the CSV file
-     * @throws CsvValidationException If a user-supplied validator declares the
-     *   data to be invalid
+     * @throws CsvFieldAssignmentException A more specific subclass of this
+     *   exception is thrown for any problem decoding and assigning a field
+     *   of the input to a bean field
+     * @throws CsvChainedException If multiple exceptions are thrown for the
+     * same input line
      */
     private T processLine()
             throws CsvBeanIntrospectionException,
-            CsvBadConverterException, CsvDataTypeMismatchException,
-            CsvRequiredFieldEmptyException, CsvConstraintViolationException,
-            CsvValidationException {
+            CsvBadConverterException, CsvFieldAssignmentException,
+            CsvChainedException {
         return mapper.populateNewBean(line);
     }
 }
diff --git a/src/main/java/com/opencsv/bean/util/OpencsvUtils.java b/src/main/java/com/opencsv/bean/util/OpencsvUtils.java
index e2aeff5..380a481 100644
--- a/src/main/java/com/opencsv/bean/util/OpencsvUtils.java
+++ b/src/main/java/com/opencsv/bean/util/OpencsvUtils.java
@@ -19,13 +19,12 @@ import com.opencsv.ICSVParser;
 import com.opencsv.bean.*;
 import com.opencsv.bean.exceptionhandler.CsvExceptionHandler;
 import com.opencsv.exceptions.CsvBadConverterException;
+import com.opencsv.exceptions.CsvChainedException;
 import com.opencsv.exceptions.CsvException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
 
-import java.util.IllegalFormatException;
-import java.util.Locale;
-import java.util.ResourceBundle;
+import java.util.*;
 import java.util.concurrent.BlockingQueue;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -115,15 +114,20 @@ public final class OpencsvUtils {
             CsvExceptionHandler exceptionHandler, BlockingQueue<OrderedObject<CsvException>> queue) {
         e.setLineNumber(lineNumber);
         CsvException capturedException = null;
-        try {
-            capturedException = exceptionHandler.handleException(e);
-        } catch (CsvException csve) {
-            capturedException = csve;
-            throw new RuntimeException(csve);
-        } finally {
-            if (capturedException != null) {
-                queueRefuseToAcceptDefeat(queue,
-                        new OrderedObject<>(lineNumber, capturedException));
+        List<CsvException> exceptionList = e instanceof CsvChainedException ?
+                Collections.<CsvException>unmodifiableList(((CsvChainedException)e).getExceptionChain()) :
+                Collections.singletonList(e);
+        for (CsvException iteratedException : exceptionList) {
+            try {
+                capturedException = exceptionHandler.handleException(iteratedException);
+            } catch (CsvException csve) {
+                capturedException = csve;
+                throw new RuntimeException(csve);
+            } finally {
+                if (capturedException != null) {
+                    queueRefuseToAcceptDefeat(queue,
+                            new OrderedObject<>(lineNumber, capturedException));
+                }
             }
         }
     }
diff --git a/src/main/java/com/opencsv/exceptions/CsvChainedException.java b/src/main/java/com/opencsv/exceptions/CsvChainedException.java
new file mode 100644
index 0000000..7315e81
--- /dev/null
+++ b/src/main/java/com/opencsv/exceptions/CsvChainedException.java
@@ -0,0 +1,77 @@
+package com.opencsv.exceptions;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * An exception class for collecting multiple exceptions.
+ * For internal use only.
+ *
+ * @author Andrew Rucker Jones
+ * @since 5.3
+ */
+public class CsvChainedException extends CsvException {
+
+    private final List<CsvFieldAssignmentException> exceptionChain = new LinkedList<>();
+
+    /**
+     * Constructor.
+     * @param csve The first exception for the list being collected.
+     *             Must not be {@code null}.
+     */
+    public CsvChainedException(CsvFieldAssignmentException csve) {
+        exceptionChain.add(csve);
+    }
+
+    /**
+     * Add an exception to the chain of collections.
+     * @param csve Exception to be added to this chain.
+     *             Must not be {@code null}.
+     */
+    public void add(CsvFieldAssignmentException csve) {
+        exceptionChain.add(csve);
+    }
+
+    /**
+     * @return A list of all exceptions collected
+     */
+    public List<CsvFieldAssignmentException> getExceptionChain() {
+        return exceptionChain;
+    }
+
+    /** Sets the line for all exceptions collected. */
+    // The rest of the Javadoc is inherited
+    @Override
+    public void setLine(String[] line) {
+        super.setLine(line);
+        exceptionChain.forEach(e -> e.setLine(line));
+    }
+
+    /** Sets the line number for all exceptions collected. */
+    // The rest of the Javadoc is inherited
+    @Override
+    public void setLineNumber(long lineNumber) {
+        super.setLineNumber(lineNumber);
+        exceptionChain.forEach(e -> e.setLineNumber(lineNumber));
+    }
+
+    /**
+     * Convenience method that checks if the chain only has a single exception.
+     *
+     * @return {@code true} if chain has only a single exception,
+     *   {@code false} otherwise
+     */
+    public boolean hasOnlyOneException() {
+        return exceptionChain.size() == 1;
+    }
+
+    /**
+     * Convenience method to return the first exception from the exception chain.
+     *
+     * @return {@link CsvFieldAssignmentException} at the first position in the
+     * list, {@code null} otherwise.
+     */
+    public CsvFieldAssignmentException getFirstException() {
+        return exceptionChain.isEmpty() ? null : exceptionChain.get(0);
+    }
+}
diff --git a/src/main/java/com/opencsv/exceptions/CsvConstraintViolationException.java b/src/main/java/com/opencsv/exceptions/CsvConstraintViolationException.java
index 390cc70..26b7d40 100644
--- a/src/main/java/com/opencsv/exceptions/CsvConstraintViolationException.java
+++ b/src/main/java/com/opencsv/exceptions/CsvConstraintViolationException.java
@@ -30,7 +30,7 @@ package com.opencsv.exceptions;
  * @author Andrew Rucker Jones
  * @since 3.8
  */
-public class CsvConstraintViolationException extends CsvException {
+public class CsvConstraintViolationException extends CsvFieldAssignmentException {
     private static final long serialVersionUID = 1L;
 
     private transient final Object sourceObject;
diff --git a/src/main/java/com/opencsv/exceptions/CsvDataTypeMismatchException.java b/src/main/java/com/opencsv/exceptions/CsvDataTypeMismatchException.java
index 563bda1..80b1bad 100644
--- a/src/main/java/com/opencsv/exceptions/CsvDataTypeMismatchException.java
+++ b/src/main/java/com/opencsv/exceptions/CsvDataTypeMismatchException.java
@@ -22,7 +22,7 @@ package com.opencsv.exceptions;
  * @author Andrew Rucker Jones
  * @since 3.8
  */
-public class CsvDataTypeMismatchException extends CsvException {
+public class CsvDataTypeMismatchException extends CsvFieldAssignmentException {
     private static final long serialVersionUID = 1L;
     
     private transient final Object sourceObject;
diff --git a/src/main/java/com/opencsv/exceptions/CsvFieldAssignmentException.java b/src/main/java/com/opencsv/exceptions/CsvFieldAssignmentException.java
new file mode 100644
index 0000000..33555bd
--- /dev/null
+++ b/src/main/java/com/opencsv/exceptions/CsvFieldAssignmentException.java
@@ -0,0 +1,22 @@
+package com.opencsv.exceptions;
+
+/**
+ * Superclass for checked exceptions that can be thrown while trying to decode
+ * and assign a single field.
+ *
+ * @author Andrew Rucker Jones
+ * @since 5.3
+ */
+public abstract class CsvFieldAssignmentException extends CsvException {
+
+    /** Nullary constructor. */
+    public CsvFieldAssignmentException() {}
+
+    /**
+     * Constructor for initializing an error message.
+     * @param message Human-readable error message
+     */
+    public CsvFieldAssignmentException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/com/opencsv/exceptions/CsvRequiredFieldEmptyException.java b/src/main/java/com/opencsv/exceptions/CsvRequiredFieldEmptyException.java
index 7812013..19e3b1a 100644
--- a/src/main/java/com/opencsv/exceptions/CsvRequiredFieldEmptyException.java
+++ b/src/main/java/com/opencsv/exceptions/CsvRequiredFieldEmptyException.java
@@ -28,7 +28,7 @@ import org.apache.commons.collections4.list.UnmodifiableList;
  * @author Andrew Rucker Jones
  * @since 3.8
  */
-public class CsvRequiredFieldEmptyException extends CsvException {
+public class CsvRequiredFieldEmptyException extends CsvFieldAssignmentException {
     private static final long serialVersionUID = 1L;
 
     private final Class<?> beanClass;
diff --git a/src/main/java/com/opencsv/exceptions/CsvValidationException.java b/src/main/java/com/opencsv/exceptions/CsvValidationException.java
index f016ad8..a7bbcdd 100644
--- a/src/main/java/com/opencsv/exceptions/CsvValidationException.java
+++ b/src/main/java/com/opencsv/exceptions/CsvValidationException.java
@@ -1,12 +1,13 @@
 package com.opencsv.exceptions;
 
 /**
- * Exception thrown by a LineValidator or LineValidatorAggregator when a single line is invalid.
+ * Exception thrown by a {@link com.opencsv.validators.LineValidator} or
+ * {@link com.opencsv.validators.LineValidatorAggregator} when a single line is invalid.
  *
  * @author Scott Conway
  * @since 5.0
  */
-public class CsvValidationException extends CsvException {
+public class CsvValidationException extends CsvFieldAssignmentException {
     private static final long serialVersionUID = 1L;
 
     /**
@@ -19,7 +20,7 @@ public class CsvValidationException extends CsvException {
     /**
      * Constructor that allows for a human readable message.
      *
-     * @param message - error text.
+     * @param message Error text.
      */
     public CsvValidationException(String message) {
         super(message);
diff --git a/src/main/resources/opencsv.properties b/src/main/resources/opencsv.properties
index 6f5b9f2..4b946b7 100644
--- a/src/main/resources/opencsv.properties
+++ b/src/main/resources/opencsv.properties
@@ -37,6 +37,7 @@ header.nonexistant=No column found for header [%s].
 header.required.field.absent=Header is missing required fields [%s]. The list of headers encountered is [%s].
 ignore.field.inconsistent=When specifying a field to ignore, both the type and the field must be non-null, and the field must be a member of the type, either directly or through inheritance.
 illegal.enum.value=The value [%1$s] is not a valid value for the enumeration type %2$s.
+invalid.currency.value=The value [%1$s] is not a valid ISO 4217 currency code.
 invalid.collection.type=The specified type for the collection is either unknown or does not implement java.util.Collection: %s
 invalid.date.format.string=The specified format string does not parse properly or cannot be used with the supplied data. The format string is: %s
 invalid.multivaluedmap.type=The specified type for the map is either unknown or does not implement org.apache.commons.collections4.MultiValuedMap: %s
diff --git a/src/main/resources/opencsv_de.properties b/src/main/resources/opencsv_de.properties
index 0f17af4..099ba21 100644
--- a/src/main/resources/opencsv_de.properties
+++ b/src/main/resources/opencsv_de.properties
@@ -37,6 +37,7 @@ header.nonexistant=Keine Spalte f\u00fcr \u00dcberschrift [%s] gefunden.
 header.required.field.absent=Der \u00dcberschriftzeile fehlen die Pflichtfelder [%s]. Die Liste der gefundenen \u00dcberschriften enth\u00e4lt [%s].
 ignore.field.inconsistent=Bei Angabe eines zu ignorierenden Feldes dürfen weder Typ noch Feld Null sein, und das Feld muss entweder direkt oder indirekt über die Vererbung ein Mitglied vom Typ sein.
 illegal.enum.value=Der Wert [%1$s] ist für den Aufzählungstyp %2$s ungültig.
+invalid.currency.value=[%1$s] is kein gültiger ISO-4217-Code.
 invalid.collection.type=Der angegebene Sammeltyp (Collection) ist entweder unbekannt oder implementiert java.util.Collection nicht: %s
 invalid.date.format.string=Die angegebene Formattierungszeichenkette ist ungültig oder passt nicht zu den gegebenen Daten. Die Formattierungszeichenkette lautet: %s
 invalid.multivaluedmap.type=Der angegebene \u00dcbersetzungstyp (Map) ist entweder unbekannt oder implementiert org.apache.commons.collections4.MultiValuedMap nicht: %s
diff --git a/src/main/resources/opencsv_en.properties b/src/main/resources/opencsv_en.properties
index 12f6952..444297a 100644
--- a/src/main/resources/opencsv_en.properties
+++ b/src/main/resources/opencsv_en.properties
@@ -37,6 +37,7 @@ header.nonexistant=No column found for header [%s].
 header.required.field.absent=Header is missing required fields [%s]. The list of headers encountered is [%s].
 ignore.field.inconsistent=When specifying a field to ignore, both the type and the field must be non-null, and the field must be a member of the type, either directly or through inheritance.
 illegal.enum.value=The value [%1$s] is not a valid value for the enumeration type %2$s.
+invalid.currency.value=The value [%1$s] is not a valid ISO 4217 currency code.
 invalid.collection.type=The specified type for the collection is either unknown or does not implement java.util.Collection: %s
 invalid.date.format.string=The specified format string does not parse properly or cannot be used with the supplied data. The format string is: %s
 invalid.multivaluedmap.type=The specified type for the map is either unknown or does not implement org.apache.commons.collections4.MultiValuedMap: %s
diff --git a/src/main/resources/opencsv_fr.properties b/src/main/resources/opencsv_fr.properties
index 7b465cf..2a3c4c0 100644
--- a/src/main/resources/opencsv_fr.properties
+++ b/src/main/resources/opencsv_fr.properties
@@ -23,6 +23,7 @@ header.nonexistant=Pas de colonne pour l''en-tête [%s].
 header.required.field.absent=En-tête manquant pour le champ [%s]. Liste des en-têtes trouvés [%s].
 ignore.field.inconsistent=Lors de la spécification d''un champ à ignorer, le type et le champ doivent être non nulls, et le champ doit être membre du type, directement ou par héritage.
 illegal.enum.value=La valeur [%1$s] n'est pas une valeur valide pour le type d'énumération %2$s. [Google Translate]
+invalid.currency.value=[%1$s] n'est pas un code ISO 4217 valide.
 invalid.collection.type=Le type spécifié pour la collection est inconnu, ou n''implémente pas java.util.Collection: %s.
 invalid.date.format.string=Le format spécifié pour la chaîne de caractères n''est pas parsé correctement ou ne peut être utilisé avec les données fournies. Le format est : %s.
 invalid.multivaluedmap.type=Le type spécifié pour la map est inconnu, ou n''implémente pas org.apache.commons.collections4.MultiValuedMap: %s.
diff --git a/src/main/resources/opencsv_pt_BR.properties b/src/main/resources/opencsv_pt_BR.properties
index 9afdc0e..03a8d36 100644
--- a/src/main/resources/opencsv_pt_BR.properties
+++ b/src/main/resources/opencsv_pt_BR.properties
@@ -37,6 +37,7 @@ header.nonexistant=Coluna n\u00E3o encontrada para cabe\u00E7alho [%s].
 header.required.field.absent=Cabe\u00E7alho n\u00E2o cont\u00E9m campos obrigat\u00F3rios [%s]. A lista de cabe\u00E7alhos encontrados \u00E9 [%s].
 ignore.field.inconsistent=Quando especificado um campo a ser ignorado, tanto o tipo quanto o campo devem ser n\u00E3o-nulos. E o campo deve ser um membro do tipo, seja direta ou diretamente.
 illegal.enum.value=O valor [%1$s] não é válido para o enum %2$s.
+invalid.currency.value=[%1$s] não é um código ISO 4217 válido.
 invalid.collection.type=O tipo especificado para a cole\u00E7\u00E3o \u00E9 desconhecida ou n\u00E3o implementa java.util.Collection: %s
 invalid.date.format.string=O formato especificado para a string n\u00E3o pode ser corretamente interpretado ou n\u00E3o pode ser utilisado com os dados fornecidos. O formato da string \u00E9: %s
 invalid.multivaluedmap.type=O tipo especificado para o mapa \u00E9 desconhecido ou n\u00E3o implementa org.apache.commons.collections4.MultiValuedMap: %s
diff --git a/src/site/asciidoc/dev-reading.adoc b/src/site/asciidoc/dev-reading.adoc
index daf9733..0eb91ca 100644
--- a/src/site/asciidoc/dev-reading.adoc
+++ b/src/site/asciidoc/dev-reading.adoc
@@ -152,13 +152,13 @@ Here we simply name the fields identically to the header names. After that,
 reading is a simple job:
 [source, java]
 ----
-     List<Visitors> beans = new CsvToBeanBuilder(FileReader("yourfile.csv"))
+     List<Visitors> beans = new CsvToBeanBuilder(new FileReader("yourfile.csv"))
        .withType(Visitors.class).build().parse();
 ----
 
 This will give you a list of the two beans as defined in the example input file.
 Note how type conversions to basic data types (wrapped and unwrapped primitives,
-enumerations, and Strings) occur automatically.
+enumerations, Strings, and java.util.Currency) occur automatically.
 
 Input can get more complicated, though, and opencsv gives you the tools to deal
 with that. Let's start with the possibility that the header names can't be
@@ -259,6 +259,11 @@ thing to say about them: input is checked against the declared values of the
 enumeration type **without regard to case**. On writing, the enumeration value
 will always be written exactly as declared.
 
+====== Currency
+
+Converting to and from ISO 4217 currency codes via java.util.Currency works
+exactly like regular primitive fields.
+
 ====== Locales, dates, numbers
 We've considered simple data types, but we haven't considered more complex yet
 common data types. We have also not considered locales other than the default
@@ -870,7 +875,7 @@ And use this code for reading:
 ----
 MappingStrategy<MyBean> strategy = new FuzzyMappingStrategy<>();
 strategy.setType(MyBean.class);
-List<MyBean> beans = new CsvToBeanBuilder(FileReader("yourfile.csv"))
+List<MyBean> beans = new CsvToBeanBuilder(new FileReader("yourfile.csv"))
     .withMappingStrategy(strategy)
     .build()
     .parse();
diff --git a/src/test/java/com/opencsv/bean/AnnotationTest.java b/src/test/java/com/opencsv/bean/AnnotationTest.java
index fad9ba9..bf79601 100644
--- a/src/test/java/com/opencsv/bean/AnnotationTest.java
+++ b/src/test/java/com/opencsv/bean/AnnotationTest.java
@@ -122,6 +122,26 @@ public class AnnotationTest {
         testGoodData(strat, fin, true);
     }
 
+    /**
+     * "Anonymous headers" is a term someone came up with for empty headers.
+     * If empty fields are converted to {@code null}, these null headers can't
+     * break opencsv. They are not supported, but they can't cause a crash.
+     * @throws FileNotFoundException Never
+     */
+    @Test
+    public void testAnonymousHeaders() throws FileNotFoundException {
+        HeaderColumnNameMappingStrategy<AnnotatedMockBeanFull> strat =
+                new HeaderColumnNameMappingStrategy<>();
+        strat.setType(AnnotatedMockBeanFull.class);
+        FileReader fin = new FileReader("src/test/resources/testAnonymousHeaders.csv");
+        List<AnnotatedMockBeanFull> beanList = new CsvToBeanBuilder<AnnotatedMockBeanFull>(fin)
+                .withSeparator(';')
+                .withMappingStrategy(strat)
+                .withFieldAsNull(CSVReaderNullFieldIndicator.EMPTY_SEPARATORS)
+                .build().parse();
+        assertEquals(2, beanList.size());
+    }
+
     @Test
     public void testCaptureWithNullField() throws FileNotFoundException {
         HeaderColumnNameMappingStrategy<AnnotatedMockBeanFull> strat =
@@ -303,6 +323,7 @@ public class AnnotationTest {
             assertEquals(new GregorianCalendar(2018, 11, 13).getTimeInMillis(), bean.getGcalFormatSetLocale().getTimeInMillis());
             assertEquals(1.01, bean.getFloatBadLocale(), 0.001);
             assertEquals(TestEnum.TEST1, bean.getTestEnum());
+            assertEquals(Currency.getInstance("EUR"), bean.getTestCurrency());
             assertNull(bean.getColumnDoesntExist());
             assertNull(bean.getUnmapped());
 
@@ -649,6 +670,29 @@ public class AnnotationTest {
         assertEquals(String.class, innere.getDestinationClass());
     }
 
+    @Test
+    public void testMultipleExceptionsPerLine() throws FileNotFoundException {
+        ColumnPositionMappingStrategy<AnnotatedMockBeanFull> strat =
+                new ColumnPositionMappingStrategy<>();
+        strat.setType(AnnotatedMockBeanFull.class);
+        Reader fin = new FileReader("src/test/resources/testMultipleExceptionsPerLine.csv");
+        CsvToBean<AnnotatedMockBeanFull> ctb = new CsvToBeanBuilder<AnnotatedMockBeanFull>(fin)
+                .withMappingStrategy(strat)
+                .withSeparator(';')
+                .withThrowExceptions(false)
+                .build();
+        ctb.parse();
+        List<CsvException> exceptionList = ctb.getCapturedExceptions();
+        assertNotNull(exceptionList);
+        assertEquals(6, exceptionList.size()); // Two lines, three mistakes per line
+        assertEquals(1, exceptionList.get(0).getLineNumber());
+        assertEquals(1, exceptionList.get(1).getLineNumber());
+        assertEquals(1, exceptionList.get(2).getLineNumber());
+        assertEquals(2, exceptionList.get(3).getLineNumber());
+        assertEquals(2, exceptionList.get(4).getLineNumber());
+        assertEquals(2, exceptionList.get(5).getLineNumber());
+    }
+
     @Test
     public void testRequiredDateEmptyInput() throws IOException {
         for(String fn : Arrays.asList(
@@ -1150,4 +1194,22 @@ public class AnnotationTest {
             assertFalse(StringUtils.isEmpty(csve.getMessage()));
         }
     }
+
+    @Test
+    public void testIllegalCurrency() throws IOException {
+        try {
+            new CsvToBeanBuilder<AnnotatedMockBeanFull>(new FileReader("src/test/resources/testIllegalCurrency.csv"))
+                    .withType(AnnotatedMockBeanFull.class)
+                    .withSeparator(';')
+                    .build().parse();
+        }
+        catch (RuntimeException e) {
+            assertTrue(e.getCause() instanceof CsvDataTypeMismatchException);
+            CsvDataTypeMismatchException csve = (CsvDataTypeMismatchException) e.getCause();
+            assertEquals(Currency.class, csve.getDestinationClass());
+            assertEquals("illegalCurrency", csve.getSourceObject());
+            assertEquals(1L, csve.getLineNumber());
+            assertFalse(StringUtils.isEmpty(csve.getMessage()));
+        }
+    }
 }
diff --git a/src/test/java/com/opencsv/bean/CollectionSplitTest.java b/src/test/java/com/opencsv/bean/CollectionSplitTest.java
index 0cc3e0d..e79e486 100644
--- a/src/test/java/com/opencsv/bean/CollectionSplitTest.java
+++ b/src/test/java/com/opencsv/bean/CollectionSplitTest.java
@@ -352,7 +352,7 @@ public class CollectionSplitTest {
     
     @Test
     public void testUnknownElementType() {
-        final String input = "$45";
+        final String input = "America/New_York";
         CsvToBean<UnknownElementType> csv2b = new CsvToBeanBuilder<UnknownElementType>(new StringReader(input))
                 .withType(UnknownElementType.class)
                 .withThrowExceptions(false)
@@ -365,7 +365,7 @@ public class CollectionSplitTest {
         CsvDataTypeMismatchException dtme = (CsvDataTypeMismatchException) csve;
         assertEquals(1, dtme.getLineNumber());
         assertNotNull(dtme.getLine());
-        assertEquals(Currency.class, dtme.getDestinationClass());
+        assertEquals(TimeZone.class, dtme.getDestinationClass());
         assertEquals(input, dtme.getSourceObject());
     }
     
diff --git a/src/test/java/com/opencsv/bean/ExceptionHandlerTest.java b/src/test/java/com/opencsv/bean/ExceptionHandlerTest.java
index d7505e5..6f6d779 100644
--- a/src/test/java/com/opencsv/bean/ExceptionHandlerTest.java
+++ b/src/test/java/com/opencsv/bean/ExceptionHandlerTest.java
@@ -32,7 +32,7 @@ public class ExceptionHandlerTest {
      * @throws IOException Never
      */
     @Test
-    public synchronized void testReadWithExceptionHandler() throws IOException {
+    public void testReadWithExceptionHandler() throws IOException {
         CsvToBean<AnnotatedMockBeanFull> ctb = new CsvToBeanBuilder<AnnotatedMockBeanFull>(new FileReader("src/test/resources/testinputcase7.csv"))
                 .withSeparator(';')
                 .withType(AnnotatedMockBeanFull.class)
@@ -47,7 +47,7 @@ public class ExceptionHandlerTest {
     }
 
     @Test
-    public synchronized void testLambdaExceptionHandler() throws IOException {
+    public void testLambdaExceptionHandler() throws IOException {
         final String testString = "test";
         CsvToBean<AnnotatedMockBeanFull> ctb = new CsvToBeanBuilder<AnnotatedMockBeanFull>(new FileReader("src/test/resources/testinputcase7.csv"))
                 .withSeparator(';')
@@ -67,7 +67,7 @@ public class ExceptionHandlerTest {
     }
 
     @Test
-    public synchronized void testReadWithQueueThenThrowHandler() throws IOException {
+    public void testReadWithQueueThenThrowHandler() throws IOException {
         BufferedReader inFile = Files.newBufferedReader(FileSystems.getDefault().getPath("src/test/resources/testinputcase85.csv"));
         String goodLine = inFile.readLine();
         String badLine = inFile.readLine();
@@ -112,7 +112,7 @@ public class ExceptionHandlerTest {
      */
     @DisplayName("Test ExceptionHandlerIgnoreThenThrowAfter when the max number of exceptions is less than the actual number of exceptions.")
     @Test
-    public synchronized void testWriteWithIgnoreExceptionHandlerSmallNumberOfExceptions() throws IOException, CsvDataTypeMismatchException {
+    public void testWriteWithIgnoreExceptionHandlerSmallNumberOfExceptions() throws IOException, CsvDataTypeMismatchException {
         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
         AnnotatedMockBeanFull goodBean = beans.left;
         AnnotatedMockBeanFull badBean = beans.right;
@@ -157,7 +157,7 @@ public class ExceptionHandlerTest {
      */
     @DisplayName("Test ExceptionHandlerIgnoreThenThrowAfter when the max number of exceptions is greater than the actual number of exceptions.")
     @Test
-    public synchronized void testWriteWithIgnoreExceptionHandlerLargeMaxExceptions() throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
+    public void testWriteWithIgnoreExceptionHandlerLargeMaxExceptions() throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
         AnnotatedMockBeanFull goodBean = beans.left;
         AnnotatedMockBeanFull badBean = beans.right;
@@ -195,7 +195,7 @@ public class ExceptionHandlerTest {
      */
     @DisplayName("Test ExceptionHandlerQueueThenThrowAfter when the max number of exceptions is less than the actual number of exceptions.")
     @Test
-    public synchronized void testWriteWithQueueExceptionHandlerSmallNumberOfExceptions() throws IOException, CsvDataTypeMismatchException {
+    public void testWriteWithQueueExceptionHandlerSmallNumberOfExceptions() throws IOException, CsvDataTypeMismatchException {
         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
         AnnotatedMockBeanFull goodBean = beans.left;
         AnnotatedMockBeanFull badBean = beans.right;
@@ -242,7 +242,7 @@ public class ExceptionHandlerTest {
      */
     @DisplayName("Test ExceptionHandlerQueueThenThrowAfter when the max number of exceptions is greater than the actual number of exceptions.")
     @Test
-    public synchronized void testWriteWithQueueExceptionHandlerLargeMaxExceptions() throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
+    public void testWriteWithQueueExceptionHandlerLargeMaxExceptions() throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
         AnnotatedMockBeanFull goodBean = beans.left;
         AnnotatedMockBeanFull badBean = beans.right;
@@ -270,7 +270,7 @@ public class ExceptionHandlerTest {
     }
 
     @Test
-    public synchronized void testQueueThenThrowExceptionHandler() throws IOException, CsvDataTypeMismatchException {
+    public void testQueueThenThrowExceptionHandler() throws IOException, CsvDataTypeMismatchException {
         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
         AnnotatedMockBeanFull goodBean = beans.left;
         AnnotatedMockBeanFull badBean = beans.right;
diff --git a/src/test/java/com/opencsv/bean/NumberTest.java b/src/test/java/com/opencsv/bean/NumberTest.java
index a72e232..dbfcc34 100644
--- a/src/test/java/com/opencsv/bean/NumberTest.java
+++ b/src/test/java/com/opencsv/bean/NumberTest.java
@@ -326,12 +326,14 @@ public class NumberTest {
     /**
      * Tests writing numerical values using {@link CsvNumber} and the column
      * position mapping strategy.
-     * <p>Also incidentally tests:
-     * <ul><li>Using a different format string for writing than reading</li>
+     * Also incidentally tests:
+     * <ul>
+     * <li>Using a different format string for writing than reading</li>
      * <li>Using a different format string for writing, but leaving
-     * {@link CsvNumber#writeFormatEqualsReadFormat()} {@code true}</li></ul></p>
+     * {@link CsvNumber#writeFormatEqualsReadFormat()} {@code true}</li>
+     * </ul>
      *
-     * @throws IOException Never thrown
+     * @throws IOException  Never thrown
      * @throws CsvException Never thrown
      */
     @Test
diff --git a/src/test/java/com/opencsv/bean/StatefulBeanToCsvTest.java b/src/test/java/com/opencsv/bean/StatefulBeanToCsvTest.java
index b87c718..ce2f078 100644
--- a/src/test/java/com/opencsv/bean/StatefulBeanToCsvTest.java
+++ b/src/test/java/com/opencsv/bean/StatefulBeanToCsvTest.java
@@ -20,6 +20,7 @@ import com.opencsv.TestUtils;
 import com.opencsv.bean.mocks.*;
 import com.opencsv.exceptions.CsvDataTypeMismatchException;
 import com.opencsv.exceptions.CsvException;
+import com.opencsv.exceptions.CsvFieldAssignmentException;
 import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.junit.jupiter.api.AfterEach;
@@ -48,21 +49,21 @@ public class StatefulBeanToCsvTest {
     // handling of the same locale in different Java versions. There was a break from
     // Java 8 to Java 9, and another from Java 12 to Java 13.
     private static final String EXTRA_STRING_FOR_WRITING = "extrastringforwritinghowcreative";
-    private static final String GOOD_DATA_1 = "test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
-    private static final String GOOD_DATA_2 = "test string;;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T163209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;Test2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
+    private static final String GOOD_DATA_1 = "test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;EUR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
+    private static final String GOOD_DATA_2 = "test string;;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T163209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;Test2;CHF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
     private static final String GOOD_DATA_OPTIONALS_NULL = "test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T063209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
     private static final String GOOD_DATA_CUSTOM_1 = "inside custom converter;wahr;falsch;127;127;127;;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;3.4028235E38;3.4028235E38;3.4028235E38;3.4028235E38;2147483647;2147483647;2147483647;2147483647;9223372036854775807;9223372036854775807;9223372036854775807;9223372036854775807;32767;32767;32767;32767;\uFFFF;\uFFFF;10;10;10;10;;;;;;;;;;;;;falsch;wahr;really long test string, yeah!;1.a.long,long.string1;2147483645.z.Inserted in setter methodlong,long.string2;3.c.long,long.derived.string3;inside custom converter";
-    private static final String HEADER_NAME_FULL = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
-    private static final String GOOD_DATA_NAME_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;1.000,2;2000.3;3.000,4;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
+    private static final String HEADER_NAME_FULL = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;CURRENCY1;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
+    private static final String GOOD_DATA_NAME_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;EUR;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;1.000,2;2000.3;3.000,4;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
     private static final String HEADER_NAME_FULL_CUSTOM = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOL2;BOOL3;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;CHAR1;CHAR2;COMPLEX1;COMPLEX2;COMPLEX3;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;FLOAT1;FLOAT2;FLOAT3;FLOAT4;INTEGER1;INTEGER2;INTEGER3;INTEGER4;LONG1;LONG2;LONG3;LONG4;REQUIREDWITHCUSTOM;SHORT1;SHORT2;SHORT3;SHORT4;STRING1;STRING2";
     private static final String GOOD_DATA_NAME_CUSTOM_1 = "10;10;10;10;wahr;falsch;wahr;falsch;127;127;127;\uFFFF;\uFFFF;1.a.long,long.string1;2147483645.z.Inserted in setter methodlong,long.string2;3.c.long,long.derived.string3;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;3.4028235E38;3.4028235E38;3.4028235E38;3.4028235E38;2147483647;2147483647;2147483647;2147483647;9223372036854775807;9223372036854775807;9223372036854775807;9223372036854775807;inside custom converter;32767;32767;32767;32767;inside custom converter;really long test string, yeah!";
     private static final String GOOD_DATA_NAME_CUSTOM_2 = "10;10;10;10;wahr;falsch;wahr;falsch;127;127;127;\uFFFF;\uFFFF;4.d.long,long.string4;2147483642.z.Inserted in setter methodlong,long.derived.string5;6.f.long,long.string6;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;3.4028235E38;3.4028235E38;3.4028235E38;3.4028235E38;2147483647;2147483647;2147483647;2147483647;9223372036854775807;9223372036854775807;9223372036854775807;9223372036854775807;inside custom converter;32767;32767;32767;32767;inside custom converter;really";
-    private static final String HEADER_NAME_FULL_DERIVED = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INT IN SUBCLASS;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
-    private static final String GOOD_DATA_NAME_DERIVED_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;7;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
-    private static final String GOOD_DATA_NAME_DERIVED_SUB_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
-    private static final String REVERSE_GOOD_DATA_1 = ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;TEST1;1.01;19780115T063209;19780115T063209;13. Dezember 2018;01/15/1978;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;102;101;123.102,102;123101.101;b;a;16.000;15000;14.000;13000;12.000;11000;10.000;9000;8.000;2147476647;6.000;5000;3.000,4;2000.3;1.000,2;123101.1;123(\u00A0|\u202F)404,404;123303.303;123.202,202;123,101.101;4;3;2;1;false;value: true;test string";
-    private static final String COLLATED_HEADER_NAME_FULL = "SHORT1;SHORT2;SHORT3;SHORT4;STRING1;BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOLPRIMITIVE;BOOL1;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4";
-    private static final String COLLATED_GOOD_DATA_NAME_1 = "13000;14.000;15000;16.000;test string;123101.101;123.102,102;101;102;false;value: true;1;2;3;4;a;b;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;1.000,2;2000.3;3.000,4;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000";
+    private static final String HEADER_NAME_FULL_DERIVED = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;CURRENCY1;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INT IN SUBCLASS;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
+    private static final String GOOD_DATA_NAME_DERIVED_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;EUR;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;7;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
+    private static final String GOOD_DATA_NAME_DERIVED_SUB_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;EUR;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
+    private static final String REVERSE_GOOD_DATA_1 = ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EUR;TEST1;1.01;19780115T063209;19780115T063209;13. Dezember 2018;01/15/1978;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;102;101;123.102,102;123101.101;b;a;16.000;15000;14.000;13000;12.000;11000;10.000;9000;8.000;2147476647;6.000;5000;3.000,4;2000.3;1.000,2;123101.1;123(\u00A0|\u202F)404,404;123303.303;123.202,202;123,101.101;4;3;2;1;false;value: true;test string";
+    private static final String COLLATED_HEADER_NAME_FULL = "SHORT1;SHORT2;SHORT3;SHORT4;STRING1;BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOLPRIMITIVE;BOOL1;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;CURRENCY1;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4";
+    private static final String COLLATED_GOOD_DATA_NAME_1 = "13000;14.000;15000;16.000;test string;123101.101;123.102,102;101;102;false;value: true;1;2;3;4;a;b;EUR;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;1.000,2;2000.3;3.000,4;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000";
 
     @BeforeAll
     public static void storeSystemLocale() {
@@ -129,7 +130,7 @@ public class StatefulBeanToCsvTest {
         btcsv.write(beans.left);
         String output = writer.toString();
         assertTrue(Pattern.matches(
-                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
+                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"EUR\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
                 output));
     }
 
@@ -144,7 +145,7 @@ public class StatefulBeanToCsvTest {
         beans.left.setStringClass("Quoted \"air quotes\" string");
         btcsv.write(beans.left);
         assertTrue(Pattern.matches(
-                "\"Quoted \"\"air quotes\"\" string\";value: true;false;1;2;3;4;123,101\\.101;123\\.202,202;123303\\.303;123(\u00A0|\u202F)404,404;123101\\.1;1\\.000,2;2000\\.3;3\\.000,4;5000;6\\.000;2147476647;8\\.000;9000;10\\.000;11000;12\\.000;13000;14\\.000;15000;16\\.000;a;b;123101\\.101;123\\.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13\\. Dezember 2018;19780115T063209;19780115T063209;1\\.01;TEST1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n",
+                "\"Quoted \"\"air quotes\"\" string\";value: true;false;1;2;3;4;123,101\\.101;123\\.202,202;123303\\.303;123(\u00A0|\u202F)404,404;123101\\.1;1\\.000,2;2000\\.3;3\\.000,4;5000;6\\.000;2147476647;8\\.000;9000;10\\.000;11000;12\\.000;13000;14\\.000;15000;16\\.000;a;b;123101\\.101;123\\.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13\\. Dezember 2018;19780115T063209;19780115T063209;1\\.01;TEST1;EUR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n",
                 writer.toString()));
     }
 
@@ -316,6 +317,7 @@ public class StatefulBeanToCsvTest {
         beans.left.setFloatWrappedDefaultLocale(null);
         beans.left.setCalDefaultLocale(null);
         beans.left.setTestEnum(null);
+        beans.left.setTestCurrency(null);
         StringWriter writer = new StringWriter();
         StatefulBeanToCsv<AnnotatedMockBeanFull> btcsv = new StatefulBeanToCsvBuilder<AnnotatedMockBeanFull>(writer)
                 .withQuotechar(ICSVWriter.NO_QUOTE_CHARACTER)
@@ -1000,6 +1002,35 @@ public class StatefulBeanToCsvTest {
         assertTrue(Pattern.matches(HEADER_NAME_FULL + "\n" + GOOD_DATA_NAME_1 + "\n", writer.toString()));
     }
 
+    @Test
+    public void writeMultipleExceptionsPerBean() throws CsvFieldAssignmentException {
+        StringWriter writer = new StringWriter();
+        HeaderColumnNameMappingStrategy<WriteLocale> strat = new HeaderColumnNameMappingStrategy<>();
+        strat.setColumnOrderOnWrite(null);
+        strat.setType(WriteLocale.class);
+        StatefulBeanToCsv<WriteLocale> btcsv = new StatefulBeanToCsvBuilder<WriteLocale>(writer)
+                .withQuotechar(ICSVWriter.NO_QUOTE_CHARACTER)
+                .withSeparator(';')
+                .withMappingStrategy(strat)
+                .withThrowExceptions(false)
+                .build();
+
+        // Broken beans. Each has multiple required fields.
+        List<WriteLocale> beans = Arrays.asList(new WriteLocale(), new WriteLocale(), new WriteLocale());
+        btcsv.write(beans);
+        List<CsvException> thrownExceptions = btcsv.getCapturedExceptions();
+        assertNotNull(thrownExceptions);
+        assertEquals(12, thrownExceptions.size());
+        final int errorsPerLine = 4;
+        for(int line = 0; line < 3 ; line++) {
+            for(int mistake = 0; mistake < errorsPerLine; mistake++) {
+                CsvException e = thrownExceptions.get(line*errorsPerLine+mistake);
+                assertTrue(e instanceof CsvRequiredFieldEmptyException);
+                assertEquals(line+1, e.getLineNumber());
+            }
+        }
+    }
+
     private static class SFirstCollator implements Comparator<String> {
         private final Comparator<Object> c;
 
diff --git a/src/test/java/com/opencsv/bean/StatefulBeanToCsvWithCSVWriterTest.java b/src/test/java/com/opencsv/bean/StatefulBeanToCsvWithCSVWriterTest.java
index c32b25c..4ce1704 100644
--- a/src/test/java/com/opencsv/bean/StatefulBeanToCsvWithCSVWriterTest.java
+++ b/src/test/java/com/opencsv/bean/StatefulBeanToCsvWithCSVWriterTest.java
@@ -50,18 +50,18 @@ public class StatefulBeanToCsvWithCSVWriterTest {
     // handling of the same locale in different Java versions. There was a break from
     // Java 8 to Java 9, and another from Java 12 to Java 13.
     private static final String EXTRA_STRING_FOR_WRITING = "extrastringforwritinghowcreative";
-    private static final String GOOD_DATA_1 = "test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
-    private static final String GOOD_DATA_2 = "test string;;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T163209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;Test2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
-    private static final String GOOD_DATA_OPTIONALS_NULL = "test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T063209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
+    private static final String GOOD_DATA_1 = "test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;EUR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
+    private static final String GOOD_DATA_2 = "test string;;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;123101.1;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T163209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;Test2;CHF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
+    private static final String GOOD_DATA_OPTIONALS_NULL = "test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;;1.000,2;2000.3;3.000,4;5000;6.000;2147476647;8.000;9000;10.000;11000;12.000;13000;14.000;15000;16.000;a;b;123101.101;123.102,102;101;102;19780115T063209;19780115T063209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;";
     private static final String GOOD_DATA_CUSTOM_1 = "inside custom converter;wahr;falsch;127;127;127;;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;3.4028235E38;3.4028235E38;3.4028235E38;3.4028235E38;2147483647;2147483647;2147483647;2147483647;9223372036854775807;9223372036854775807;9223372036854775807;9223372036854775807;32767;32767;32767;32767;\uFFFF;\uFFFF;10;10;10;10;;;;;;;;;;;;;falsch;wahr;really long test string, yeah!;1.a.long,long.string1;2147483645.z.Inserted in setter methodlong,long.string2;3.c.long,long.derived.string3;inside custom converter";
-    private static final String HEADER_NAME_FULL = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
-    private static final String GOOD_DATA_NAME_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;1.000,2;2000.3;3.000,4;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
+    private static final String HEADER_NAME_FULL = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;CURRENCY1;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
+    private static final String GOOD_DATA_NAME_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;EUR;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;1.000,2;2000.3;3.000,4;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
     private static final String HEADER_NAME_FULL_CUSTOM = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOL2;BOOL3;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;CHAR1;CHAR2;COMPLEX1;COMPLEX2;COMPLEX3;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;FLOAT1;FLOAT2;FLOAT3;FLOAT4;INTEGER1;INTEGER2;INTEGER3;INTEGER4;LONG1;LONG2;LONG3;LONG4;REQUIREDWITHCUSTOM;SHORT1;SHORT2;SHORT3;SHORT4;STRING1;STRING2";
     private static final String GOOD_DATA_NAME_CUSTOM_1 = "10;10;10;10;wahr;falsch;wahr;falsch;127;127;127;\uFFFF;\uFFFF;1.a.long,long.string1;2147483645.z.Inserted in setter methodlong,long.string2;3.c.long,long.derived.string3;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;3.4028235E38;3.4028235E38;3.4028235E38;3.4028235E38;2147483647;2147483647;2147483647;2147483647;9223372036854775807;9223372036854775807;9223372036854775807;9223372036854775807;inside custom converter;32767;32767;32767;32767;inside custom converter;really long test string, yeah!";
     private static final String GOOD_DATA_NAME_CUSTOM_2 = "10;10;10;10;wahr;falsch;wahr;falsch;127;127;127;\uFFFF;\uFFFF;4.d.long,long.string4;2147483642.z.Inserted in setter methodlong,long.derived.string5;6.f.long,long.string6;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;1.7976931348623157E308;3.4028235E38;3.4028235E38;3.4028235E38;3.4028235E38;2147483647;2147483647;2147483647;2147483647;9223372036854775807;9223372036854775807;9223372036854775807;9223372036854775807;inside custom converter;32767;32767;32767;32767;inside custom converter;really";
-    private static final String HEADER_NAME_FULL_DERIVED = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INT IN SUBCLASS;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
-    private static final String GOOD_DATA_NAME_DERIVED_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;7;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
-    private static final String GOOD_DATA_NAME_DERIVED_SUB_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
+    private static final String HEADER_NAME_FULL_DERIVED = "BIGDECIMAL1;BIGDECIMAL2;BIGINTEGER1;BIGINTEGER2;BOOL1;BOOLPRIMITIVE;BYTE1;BYTE2;BYTE3;BYTE4;CHAR1;CHAR2;CURRENCY1;DATE1;DATE10;DATE11;DATE12;DATE13;DATE14;DATE15;DATE16;DATE2;DATE3;DATE4;DATE5;DATE6;DATE7;DATE8;DATE9;DOUBLE1;DOUBLE2;DOUBLE3;DOUBLE4;ENUM1;FLOAT1;FLOAT2;FLOAT3;FLOAT4;FLOAT5;INT IN SUBCLASS;INTEGER1;INTEGER2;INTEGER3;INTEGER4;ITNOGOODCOLUMNITVERYBAD;LONG1;LONG2;LONG3;LONG4;SHORT1;SHORT2;SHORT3;SHORT4;STRING1";
+    private static final String GOOD_DATA_NAME_DERIVED_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;EUR;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;7;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
+    private static final String GOOD_DATA_NAME_DERIVED_SUB_1 = "123101.101;123.102,102;101;102;value: true;false;1;2;3;4;a;b;EUR;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;123,101.101;123.202,202;123303.303;123(\u00A0|\u202F)404,404;TEST1;123101.1;123.202,203;123303.305;123.404,406;1.01;5000;6.000;2147476647;8.000;;9000;10.000;11000;12.000;13000;14.000;15000;16.000;test string";
 
 
     private StringWriter writer;
@@ -133,7 +133,7 @@ public class StatefulBeanToCsvWithCSVWriterTest {
         btcsv.write(beans.left);
         String output = writer.toString();
         assertTrue(Pattern.matches(
-                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
+                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"EUR\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
                 output));
     }
 
@@ -151,7 +151,7 @@ public class StatefulBeanToCsvWithCSVWriterTest {
         btcsv.write(beans.left);
         String output = writer.toString();
         assertTrue(Pattern.matches(
-                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
+                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"EUR\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
                 output));
     }
 
@@ -168,7 +168,7 @@ public class StatefulBeanToCsvWithCSVWriterTest {
         btcsv.write(beans.left);
         String output = writer.toString();
         assertTrue(Pattern.matches(
-                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
+                "\"Quoted \"\"air quotes\"\" string\";\"value: true\";\"false\";\"1\";\"2\";\"3\";\"4\";\"123,101\\.101\";\"123\\.202,202\";\"123303\\.303\";\"123(\u00A0|\u202F)404,404\";\"123101\\.1\";\"1\\.000,2\";\"2000\\.3\";\"3\\.000,4\";\"5000\";\"6\\.000\";\"2147476647\";\"8\\.000\";\"9000\";\"10\\.000\";\"11000\";\"12\\.000\";\"13000\";\"14\\.000\";\"15000\";\"16\\.000\";\"a\";\"b\";\"123101\\.101\";\"123\\.102,102\";\"101\";\"102\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"19780115T063209\";\"01/15/1978\";\"13\\. Dezember 2018\";\"19780115T063209\";\"19780115T063209\";\"1\\.01\";\"TEST1\";\"EUR\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\";\"\"\n",
                 output));
     }
 
@@ -184,7 +184,7 @@ public class StatefulBeanToCsvWithCSVWriterTest {
         beans.left.setStringClass("Quoted \"air quotes\" string");
         btcsv.write(beans.left);
         assertTrue(Pattern.matches(
-                "\"Quoted \"\"air quotes\"\" string\";value: true;false;1;2;3;4;123,101\\.101;123\\.202,202;123303\\.303;123(\u00A0|\u202F)404,404;123101\\.1;1\\.000,2;2000\\.3;3\\.000,4;5000;6\\.000;2147476647;8\\.000;9000;10\\.000;11000;12\\.000;13000;14\\.000;15000;16\\.000;a;b;123101\\.101;123\\.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13\\. Dezember 2018;19780115T063209;19780115T063209;1\\.01;TEST1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n",
+                "\"Quoted \"\"air quotes\"\" string\";value: true;false;1;2;3;4;123,101\\.101;123\\.202,202;123303\\.303;123(\u00A0|\u202F)404,404;123101\\.1;1\\.000,2;2000\\.3;3\\.000,4;5000;6\\.000;2147476647;8\\.000;9000;10\\.000;11000;12\\.000;13000;14\\.000;15000;16\\.000;a;b;123101\\.101;123\\.102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13\\. Dezember 2018;19780115T063209;19780115T063209;1\\.01;TEST1;EUR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n",
                 writer.toString()));
     }
 
@@ -274,6 +274,8 @@ public class StatefulBeanToCsvWithCSVWriterTest {
         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
         beans.left.setFloatWrappedDefaultLocale(null);
         beans.left.setCalDefaultLocale(null);
+        beans.left.setTestEnum(null);
+        beans.left.setTestCurrency(null);
         ICSVWriter csvWriter = csvWriterBuilder
                 .withQuoteChar(ICSVWriter.NO_QUOTE_CHARACTER)
                 .withEscapeChar('|')
diff --git a/src/test/java/com/opencsv/bean/TemporalTest.java b/src/test/java/com/opencsv/bean/TemporalTest.java
index 460fe51..5863ff7 100644
--- a/src/test/java/com/opencsv/bean/TemporalTest.java
+++ b/src/test/java/com/opencsv/bean/TemporalTest.java
@@ -19,10 +19,9 @@ import java.io.StringWriter;
 import java.time.*;
 import java.time.chrono.*;
 import java.time.temporal.Temporal;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
+import java.util.*;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import static org.junit.Assert.*;
 
@@ -220,27 +219,21 @@ public class TemporalTest {
 
         List<CsvException> exceptions = csvToBean.getCapturedExceptions();
         assertNotNull(exceptions);
-        assertEquals(5, exceptions.size());
 
-        // The exception we're looking for could be the third or fourth
-        assertTrue(verifyEraException(exceptions.get(2), 4, era)
-                || verifyEraException(exceptions.get(3), 5, era)
-                || verifyEraException(exceptions.get(4), 6, era));
-    }
+        // Five lines must show errors
+        assertEquals(5, exceptions.stream()
+                .map(CsvException::getLineNumber)
+                .collect(Collectors.toSet()).size());
 
-    private boolean verifyEraException(CsvException csve, long lineNumber, Class<? extends Era> era) {
-        boolean assertionPassed = true;
-        assertTrue(csve instanceof CsvDataTypeMismatchException);
-        CsvDataTypeMismatchException dtmm = (CsvDataTypeMismatchException) csve;
-        assertNotNull(dtmm.getCause());
-        if(lineNumber != dtmm.getLineNumber()) {
-            assertionPassed = false;
-        }
-        assertNotNull(dtmm.getSourceObject());
-        if(!era.equals(dtmm.getDestinationClass())) {
-            assertionPassed = false;
-        }
-        return assertionPassed;
+        // The exception we're looking for could be in one of three lines
+        Set<Long> possibleLines = new HashSet<>();
+        possibleLines.add(4L); possibleLines.add(5L); possibleLines.add(6L);
+        assertTrue(exceptions.stream()
+                .filter(e -> e.getCause() != null)
+                .filter(e -> e instanceof CsvDataTypeMismatchException)
+                .filter(e -> era.equals(((CsvDataTypeMismatchException)e).getDestinationClass()))
+                .filter(e -> ((CsvDataTypeMismatchException) e).getSourceObject() != null)
+                .anyMatch(e -> possibleLines.contains(e.getLineNumber())));
     }
 
     /**
@@ -272,8 +265,11 @@ public class TemporalTest {
         //   Japanese eras = "Shōwa" and "Taishō"
         // Thus we have three lines of input for every combination and any
         // given version of Java will accept three and throw exceptions for the
-        // other six.
-        assertEquals(6, csvToBean.getCapturedExceptions().size());
+        // other six. But there are either four or six errors per line, as well.
+        Set<Integer> numErrors = new HashSet<>();
+        numErrors.add(24); // Java 9 through 12
+        numErrors.add(36); // Java 8 and 13+
+        assertTrue(numErrors.contains(csvToBean.getCapturedExceptions().size()));
         verifyBeans(beans);
     }
 
@@ -297,8 +293,11 @@ public class TemporalTest {
         //   Japanese eras = "Shōwa" and "Taishō"
         // Thus we have three lines of input for every combination and any
         // given version of Java will accept three and throw exceptions for the
-        // other six.
-        assertEquals(6, csvToBean.getCapturedExceptions().size());
+        // other six. But there are either four or six errors per line, as well.
+        Set<Integer> numErrors = new HashSet<>();
+        numErrors.add(24); // Java 9 through 12
+        numErrors.add(36); // Java 8 and 13+
+        assertTrue(numErrors.contains(csvToBean.getCapturedExceptions().size()));
         verifyBeans(beans);
     }
 
@@ -395,15 +394,13 @@ public class TemporalTest {
         csvToBean.parse();
         List<CsvException> exceptions = csvToBean.getCapturedExceptions();
         assertNotNull(exceptions);
-        assertEquals(2, exceptions.size());
-        for(CsvException e : exceptions) {
-            assertNotNull(e.getCause());
-            assertNotNull(e.getLine());
-            assertTrue(e instanceof CsvDataTypeMismatchException);
-            CsvDataTypeMismatchException csve = (CsvDataTypeMismatchException) e;
-            assertEquals(input.split(",", 2)[0], csve.getSourceObject());
-            assertEquals(IsoEra.class, csve.getDestinationClass());
-        }
+        assertEquals(2, exceptions.stream()
+                .filter(e -> e.getCause() != null)
+                .filter(e -> e.getLine() != null)
+                .filter(e -> e instanceof CsvDataTypeMismatchException)
+                .filter(e -> IsoEra.class.equals(((CsvDataTypeMismatchException)e).getDestinationClass()))
+                .filter(e -> input.split(",", 2)[0].equals(((CsvDataTypeMismatchException)e).getSourceObject()))
+                .count());
     }
 
     @Test
diff --git a/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFull.java b/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFull.java
index 43d9297..4ae3a93 100644
--- a/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFull.java
+++ b/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFull.java
@@ -25,6 +25,7 @@ import java.math.BigInteger;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Calendar;
+import java.util.Currency;
 import java.util.Date;
 import java.util.GregorianCalendar;
 
@@ -735,10 +736,22 @@ public class AnnotatedMockBeanFull {
      * <li>{@link com.opencsv.bean.AnnotationTest#testGoodDataByName()}</li>
      * </ul>
      */
-    @CsvBindByName(column = "enum1", required = false)
-    @CsvBindByPosition(position = 50, required = false)
+    @CsvBindByName(column = "enum1")
+    @CsvBindByPosition(position = 50)
     private TestEnum testEnum;
 
+    /**
+     * Field for annotation tests.
+     * <p>Used for the following test cases, reading:</p>
+     * <ul>
+     * <li>{@link com.opencsv.bean.AnnotationTest#testGoodDataByName()}</li>
+     * <li>{@link com.opencsv.bean.AnnotationTest#testGoodDataByPosition()}</li>
+     * </ul>
+     */
+    @CsvBindByName(column = "currency1")
+    @CsvBindByPosition(position = 51)
+    private Currency testCurrency;
+
     /**
      * Field for annotation tests.
      * <p>Used for the following test cases, reading:</p>
@@ -1192,4 +1205,8 @@ public class AnnotatedMockBeanFull {
     public TestEnum getTestEnum() {return testEnum;}
 
     public void setTestEnum(TestEnum testEnum) {this.testEnum = testEnum;}
+
+    public Currency getTestCurrency() {return testCurrency;}
+
+    public void setTestCurrency(Currency testCurrency) {this.testCurrency = testCurrency;}
 }
diff --git a/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFullDerived.java b/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFullDerived.java
index 0f9e3a2..4b3ba23 100644
--- a/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFullDerived.java
+++ b/src/test/java/com/opencsv/bean/mocks/AnnotatedMockBeanFullDerived.java
@@ -38,7 +38,7 @@ public class AnnotatedMockBeanFullDerived extends AnnotatedMockBeanFull {
      * </ul>
      */
     @CsvBindByName(required = true, column = "int in subclass")
-    @CsvBindByPosition(required = true, position = 51)
+    @CsvBindByPosition(required = true, position = 52)
     private int intInSubclass;
 
     public int getIntInSubclass() {
diff --git a/src/test/java/com/opencsv/bean/mocks/split/UnknownElementType.java b/src/test/java/com/opencsv/bean/mocks/split/UnknownElementType.java
index 814a7dd..4dc7a03 100644
--- a/src/test/java/com/opencsv/bean/mocks/split/UnknownElementType.java
+++ b/src/test/java/com/opencsv/bean/mocks/split/UnknownElementType.java
@@ -16,7 +16,7 @@
 package com.opencsv.bean.mocks.split;
 
 import com.opencsv.bean.CsvBindAndSplitByPosition;
-import java.util.Currency;
+import java.util.TimeZone;
 import java.util.List;
 
 /**
@@ -25,14 +25,14 @@ import java.util.List;
  */
 public class UnknownElementType {
     
-    @CsvBindAndSplitByPosition(elementType = Currency.class, position = 0)
-    private List<Currency> l;
+    @CsvBindAndSplitByPosition(elementType = TimeZone.class, position = 0)
+    private List<TimeZone> l;
 
-    public List<Currency> getL() {
+    public List<TimeZone> getL() {
         return l;
     }
 
-    public void setL(List<Currency> l) {
+    public void setL(List<TimeZone> l) {
         this.l = l;
     }
 }
diff --git a/src/test/java/integrationTest/FR138/ConvertWordNullToNull.java b/src/test/java/integrationTest/FR138/ConvertWordNullToNull.java
new file mode 100644
index 0000000..8e83575
--- /dev/null
+++ b/src/test/java/integrationTest/FR138/ConvertWordNullToNull.java
@@ -0,0 +1,16 @@
+package integrationTest.FR138;
+
+import com.opencsv.bean.processor.StringProcessor;
+
+public class ConvertWordNullToNull implements StringProcessor {
+
+    @Override
+    public String processString(String value) {
+        return "null".equalsIgnoreCase(value) ? null : value;
+    }
+
+    @Override
+    public void setParameterString(String value) {
+        // Unused in this case as all we care about is the word "null"
+    }
+}
diff --git a/src/test/java/integrationTest/FR138/FR138MockBean.java b/src/test/java/integrationTest/FR138/FR138MockBean.java
new file mode 100644
index 0000000..7fb645e
--- /dev/null
+++ b/src/test/java/integrationTest/FR138/FR138MockBean.java
@@ -0,0 +1,103 @@
+package integrationTest.FR138;
+
+import com.opencsv.bean.processor.PreAssignmentProcessor;
+
+public class FR138MockBean {
+
+    private String name;
+    private String id;
+    private String orderNumber;
+    @PreAssignmentProcessor(processor = ConvertWordNullToNull.class)
+    private int num;
+    private double doubleNum;
+
+    public FR138MockBean() {}
+
+    public FR138MockBean(String name, String id, String orderNumber, int num, double doubleNum) {
+        this.name = name;
+        this.id = id;
+        this.orderNumber = orderNumber;
+        this.num = num;
+        this.doubleNum = doubleNum;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getOrderNumber() {
+        return orderNumber;
+    }
+
+    public void setOrderNumber(String orderNumber) {
+        this.orderNumber = orderNumber;
+    }
+
+    public int getNum() {
+        return num;
+    }
+
+    public void setNum(int num) {
+        this.num = num;
+    }
+
+    public double getDoubleNum() {
+        return doubleNum;
+    }
+
+    public void setDoubleNum(double doubleNum) {
+        this.doubleNum = doubleNum;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof FR138MockBean)) return false;
+
+        FR138MockBean mockBean = (FR138MockBean) o;
+
+        if (getNum() != mockBean.getNum()) return false;
+        if (Double.compare(mockBean.getDoubleNum(), getDoubleNum()) != 0) return false;
+        if (getName() != null ? !getName().equals(mockBean.getName()) : mockBean.getName() != null) return false;
+        if (getId() != null ? !getId().equals(mockBean.getId()) : mockBean.getId() != null) return false;
+        return !(getOrderNumber() != null ? !getOrderNumber().equals(mockBean.getOrderNumber()) : mockBean.getOrderNumber() != null);
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result;
+        long temp;
+        result = getName() != null ? getName().hashCode() : 0;
+        result = 31 * result + (getId() != null ? getId().hashCode() : 0);
+        result = 31 * result + (getOrderNumber() != null ? getOrderNumber().hashCode() : 0);
+        result = 31 * result + getNum();
+        temp = Double.doubleToLongBits(getDoubleNum());
+        result = 31 * result + (int) (temp ^ (temp >>> 32));
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "FR138MockBean{" +
+                "name='" + name + '\'' +
+                ", id='" + id + '\'' +
+                ", orderNumber='" + orderNumber + '\'' +
+                ", num=" + num +
+                ", doubleNum=" + doubleNum +
+                '}';
+    }
+
+}
diff --git a/src/test/java/integrationTest/FR138/FR138Test.java b/src/test/java/integrationTest/FR138/FR138Test.java
new file mode 100644
index 0000000..930a6dc
--- /dev/null
+++ b/src/test/java/integrationTest/FR138/FR138Test.java
@@ -0,0 +1,32 @@
+package integrationTest.FR138;
+
+import com.opencsv.bean.CsvToBeanBuilder;
+import com.opencsv.bean.HeaderColumnNameMappingStrategy;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.io.StringReader;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class FR138Test {
+    @DisplayName("Parse a Bean that has the word null for a primitive value.")
+    @Test
+    public void parseBeanThatHasNullForInt() {
+        String testString = "name,num,orderNumber\n" +
+                "kyle,123,abc123456\n" +
+                "jimmy,null,def098765";
+
+        HeaderColumnNameMappingStrategy<FR138MockBean> strategy = new HeaderColumnNameMappingStrategy<>();
+        strategy.setType(FR138MockBean.class);
+        List<FR138MockBean> beanList = new CsvToBeanBuilder<FR138MockBean>(new StringReader(testString))
+                .withMappingStrategy(strategy)
+                .build().parse(); // Extra arguments for code coverage
+
+        assertEquals(2, beanList.size());
+        assertTrue(beanList.contains(new FR138MockBean("kyle", null, "abc123456", 123, 0.0)));
+        assertTrue(beanList.contains(new FR138MockBean("jimmy", null, "def098765", 0, 0.0)));
+    }
+}
diff --git a/src/test/resources/testAnonymousHeaders.csv b/src/test/resources/testAnonymousHeaders.csv
new file mode 100644
index 0000000..439df1f
--- /dev/null
+++ b/src/test/resources/testAnonymousHeaders.csv
@@ -0,0 +1,3 @@
+string1;;bool1;;boolPrimitive;byte1;byte2;byte3;byte4;double1;double2;double3;double4;float1;float2;float3;float4;integer1;integer2;integer3;integer4;long1;long2;long3;long4;short1;short2;short3;short4;char1;char2;bigdecimal1;bigdecimal2;biginteger1;biginteger2;date1;date2;date3;date4;date5;date6;date7;date8;date9;date10;date11;date12;date13;date14;date15;date16;float5;enum1;currency1
+test string;;value: true;;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;tESt1;EUR
++test string;;;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;
diff --git a/src/test/resources/testIllegalCurrency.csv b/src/test/resources/testIllegalCurrency.csv
new file mode 100644
index 0000000..86ccb17
--- /dev/null
+++ b/src/test/resources/testIllegalCurrency.csv
@@ -0,0 +1 @@
+test string;Truth value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;Test1;illegalCurrency
diff --git a/src/test/resources/testIllegalEnumValue.csv b/src/test/resources/testIllegalEnumValue.csv
index 27960c9..3ca43f4 100644
--- a/src/test/resources/testIllegalEnumValue.csv
+++ b/src/test/resources/testIllegalEnumValue.csv
@@ -1 +1 @@
-test string;Truth value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;bogusEnumValue
+test string;Truth value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;bogusEnumValue;EUR
diff --git a/src/test/resources/testMultipleExceptionsPerLine.csv b/src/test/resources/testMultipleExceptionsPerLine.csv
new file mode 100644
index 0000000..b99eb8e
--- /dev/null
+++ b/src/test/resources/testMultipleExceptionsPerLine.csv
@@ -0,0 +1,2 @@
+test string;Truth vlue: true;bogus;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Jaener 2018;19780115T063209;19780115T063209;1.01;TEST1;EUR
+test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115XXX063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01321978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;bogus
diff --git a/src/test/resources/testinputderivedgood.csv b/src/test/resources/testinputderivedgood.csv
index 263b55c..b52b4e1 100644
--- a/src/test/resources/testinputderivedgood.csv
+++ b/src/test/resources/testinputderivedgood.csv
@@ -1,3 +1,3 @@
-string1;bool1;boolPrimitive;byte1;byte2;byte3;byte4;double1;double2;double3;double4;float1;float2;float3;float4;integer1;integer2;integer3;integer4;long1;long2;long3;long4;short1;short2;short3;short4;char1;char2;bigdecimal1;bigdecimal2;biginteger1;biginteger2;date1;date2;date3;date4;date5;date6;date7;date8;date9;date10;date11;date12;date13;date14;date15;date16;float5;enum1;int in subclass
-test string;true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;7
-+test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;8
+string1;bool1;boolPrimitive;byte1;byte2;byte3;byte4;double1;double2;double3;double4;float1;float2;float3;float4;integer1;integer2;integer3;integer4;long1;long2;long3;long4;short1;short2;short3;short4;char1;char2;bigdecimal1;bigdecimal2;biginteger1;biginteger2;date1;date2;date3;date4;date5;date6;date7;date8;date9;date10;date11;date12;date13;date14;date15;date16;float5;enum1;currency1;int in subclass
+test string;true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;EUR;7
++test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;;8
diff --git a/src/test/resources/testinputfullgood.csv b/src/test/resources/testinputfullgood.csv
index 46a2d72..d310e0b 100644
--- a/src/test/resources/testinputfullgood.csv
+++ b/src/test/resources/testinputfullgood.csv
@@ -1,3 +1,3 @@
-string1;bool1;boolPrimitive;byte1;byte2;byte3;byte4;double1;double2;double3;double4;float1;float2;float3;float4;integer1;integer2;integer3;integer4;long1;long2;long3;long4;short1;short2;short3;short4;char1;char2;bigdecimal1;bigdecimal2;biginteger1;biginteger2;date1;date2;date3;date4;date5;date6;date7;date8;date9;date10;date11;date12;date13;date14;date15;date16;float5;enum1
-test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;tESt1
-+test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;
+string1;bool1;boolPrimitive;byte1;byte2;byte3;byte4;double1;double2;double3;double4;float1;float2;float3;float4;integer1;integer2;integer3;integer4;long1;long2;long3;long4;short1;short2;short3;short4;char1;char2;bigdecimal1;bigdecimal2;biginteger1;biginteger2;date1;date2;date3;date4;date5;date6;date7;date8;date9;date10;date11;date12;date13;date14;date15;date16;float5;enum1;currency1
+test string;value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;tESt1;EUR
++test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;
diff --git a/src/test/resources/testinputposderivedgood.csv b/src/test/resources/testinputposderivedgood.csv
index acd9031..731cc43 100644
--- a/src/test/resources/testinputposderivedgood.csv
+++ b/src/test/resources/testinputposderivedgood.csv
@@ -1,2 +1,2 @@
-test string;true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;7
-+test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;8
+test string;true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;EUR;7
++test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;;8
diff --git a/src/test/resources/testinputposfullgood.csv b/src/test/resources/testinputposfullgood.csv
index 97cba29..8ffee78 100644
--- a/src/test/resources/testinputposfullgood.csv
+++ b/src/test/resources/testinputposfullgood.csv
@@ -1,2 +1,2 @@
-test string;Truth value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1
-test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;
+test string;Truth value: true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;EUR
+test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.101;123202,202;123303.303;123404,404;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;;
diff --git a/src/test/resources/testinputwriteposfullgood.csv b/src/test/resources/testinputwriteposfullgood.csv
index 0ddb13a..e9a100b 100644
--- a/src/test/resources/testinputwriteposfullgood.csv
+++ b/src/test/resources/testinputwriteposfullgood.csv
@@ -1,2 +1,2 @@
-test string;true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.1;1.000,2;2000.3;3000,4;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1
-test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.1;1.000,2;2000.3;3000,4;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;Test2
+test string;true;false;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.1;1.000,2;2000.3;3000,4;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;1.01;TEST1;EUR
+test string;;;1;2;3;4;123,101.101;123.202,202;123303.303;123404,404;123101.1;1.000,2;2000.3;3000,4;5000;6.000;7000;8000;9000;10000;11000;12000;13000;14000;15000;16000;a;b;123101.101;123102,102;101;102;19780115T063209;19780115T163209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;19780115T063209;01/15/1978;13. Dezember 2018;19780115T063209;19780115T063209;2.02;Test2;CHF

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/share/maven-repo/com/opencsv/opencsv/5.2.1-SNAPSHOT/opencsv-5.2.1-SNAPSHOT.pom
lrwxrwxrwx  root/root   /usr/share/java/opencsv-5.2.1-SNAPSHOT.jar -> opencsv.jar
lrwxrwxrwx  root/root   /usr/share/maven-repo/com/opencsv/opencsv/5.2.1-SNAPSHOT/opencsv-5.2.1-SNAPSHOT.jar -> ../../../../../java/opencsv.jar

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/share/maven-repo/com/opencsv/opencsv/5.2/opencsv-5.2.pom
lrwxrwxrwx  root/root   /usr/share/java/opencsv-5.2.jar -> opencsv.jar
lrwxrwxrwx  root/root   /usr/share/maven-repo/com/opencsv/opencsv/5.2/opencsv-5.2.jar -> ../../../../../java/opencsv.jar

Control files: lines which differ (wdiff format)

  • Depends: libcommons-beanutils-java (>= 1.9.4), libcommons-collections4-java (>= 4.4), 4.2), libcommons-lang3-java (>= 3.12.0), libcommons-text-java (>= 1.10.0) 1.9)

More details

Full run details