diff --git a/pom.xml b/pom.xml
index 9ce484af77b07d390741e2a61b088ea497643a74..ce4dc4876f751cdd8faf12155897ce829e59af36 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,6 +3,10 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
 
     <groupId>edu.unl.cse.csv_io</groupId>
     <artifactId>csv_io</artifactId>
@@ -41,6 +45,11 @@
             <version>4.12</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.opencsv</groupId>
+            <artifactId>opencsv</artifactId>
+            <version>5.0</version>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/src/main/java/edu/unl/cse/csv_io/CSVReaderWriter.java b/src/main/java/edu/unl/cse/csv_io/CSVReaderWriter.java
index 90d7e477b3c9eb2631acf018f586cf77be5ecbfe..29d1ec0a47175298a9eb7ee8ee805b843e2b27fb 100644
--- a/src/main/java/edu/unl/cse/csv_io/CSVReaderWriter.java
+++ b/src/main/java/edu/unl/cse/csv_io/CSVReaderWriter.java
@@ -2,28 +2,68 @@
  * CSV Reader/Writer, copyright (c) 2019 Christopher A. Bohn, bohn@unl.edu.
  */
 
-
 package edu.unl.cse.csv_io;
 
+import com.opencsv.CSVReaderHeaderAware;
+import com.opencsv.CSVReaderHeaderAwareBuilder;
+import com.opencsv.exceptions.CsvValidationException;
+
 import java.io.*;
 import java.net.URL;
 import java.util.*;
 
 public class CSVReaderWriter {
-    // this does not (yet) handle data elements that include commas and/or are surrounded by quotation marks
-    private static final String DELIMTER = ",";
-    private static final char BYTE_ORDER_MARK = '\ufeff';
+    @SuppressWarnings("WeakerAccess")
+    public static Set<Map<String, String>> readCSVasSet(String filename) {
+        Set<Map<String, String>> csvSet = null;
+        try (InputStreamReader inputStreamReader = new InputStreamReader(Objects.requireNonNull(
+                CSVReaderWriter.class.getClassLoader().getResourceAsStream("csv/" + filename)))) {
+            csvSet = (Set<Map<String, String>>) parseCSV(inputStreamReader, new HashSet<>());
+        } catch (NullPointerException nullPointerException) {
+            System.err.println("Check spelling of file " + filename + ".");
+            System.exit(1);
+        } catch (IOException ioException) {
+            System.err.println("Error loading " + filename + ".  " + ioException);
+            System.exit(1);
+        } catch (CsvValidationException csvValidationException) {
+            System.err.println("Could not validate a line in " + filename + ".  " + csvValidationException);
+            System.exit(1);
+        }
+        return csvSet;
+    }
 
+    private static Collection<Map<String, String>> parseCSV(InputStreamReader inputStreamReader,
+                                                            Collection<Map<String, String>> destination)
+            throws IOException, CsvValidationException {
+        Map<String, String> line;
+        try {
+            CSVReaderHeaderAware csvReader = new CSVReaderHeaderAwareBuilder(inputStreamReader).build();
+            while ((line = csvReader.readMap()) != null) {
+                destination.add(line);
+            }
+        } catch (NullPointerException ignored) {
+            // CSVReaderHeaderAwareBuilder.build() throws NullPointerException if inputStreamReader is empty
+        }
+        return destination;
+    }
+
+    /* LEGACY METHODS */
+    @SuppressWarnings("WeakerAccess")
+    public static Set<Map<String, String>> readCSV(String filename) {
+        return readCSVasSet(filename);
+    }
+/*
     public static Set<Map<String, String>> readCSV(String filename) {
         Set<Map<String, String>> csvSet = null;
         ClassLoader classLoader = CSVReaderWriter.class.getClassLoader();
-        try(InputStream inputStream = classLoader.getResourceAsStream("csv/"+filename)) {
+        try (InputStream inputStream = classLoader.getResourceAsStream("csv/" + filename)) {
             csvSet = parseCSV(inputStream);
         } catch (IOException ioException) {
             System.err.println("Error loading " + filename + ".  " + ioException);
         }
         return csvSet;
     }
+*/
 
     public static boolean writeCSV(String filename, Set<Map<String, String>> data) {
         boolean wroteFile = true;
@@ -31,7 +71,7 @@ public class CSVReaderWriter {
         URL resource = classLoader.getResource("csv/" + filename);
         if (resource != null) {
             File file = new File(resource.getPath());
-            try(OutputStream outputStream = new FileOutputStream(file)) {
+            try (OutputStream outputStream = new FileOutputStream(file)) {
                 placeCSVonStream(data, outputStream);
             } catch (FileNotFoundException fileNotFoundException) {
                 System.err.println("Could not open " + filename + "; probably due to a bad pathname.  " + fileNotFoundException);
@@ -47,6 +87,16 @@ public class CSVReaderWriter {
         return wroteFile;
     }
 
+
+    static Set<Map<String, String>> parseCSV(InputStream inputStream) throws IOException {
+        try {
+            return (Set<Map<String, String>>) parseCSV(new InputStreamReader(inputStream), new HashSet<>());
+        } catch (CsvValidationException csvValidationException) {
+            csvValidationException.printStackTrace();
+            return null;
+        }
+    }
+/*
     static Set<Map<String, String>> parseCSV(InputStream inputStream) throws IOException {
         Set<Map<String, String>> csvSet = new HashSet<>();
         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
@@ -57,14 +107,15 @@ public class CSVReaderWriter {
             String[] elements = line.split(DELIMTER);
             if (header) {
                 if (elements[0].charAt(0) == BYTE_ORDER_MARK) {
-                    elements[0] = elements[0].substring(1);     // remove text-encoding character sometimes added by Excel
+                    elements[0] = elements[0].substring(1);     // remove text-encoding character sometimes added by
+                    // Excel
                 }
                 fieldNames.addAll(Arrays.asList(elements));
                 header = false;
             } else {
                 Map<String, String> row = new HashMap<>();
                 int column = 0;
-                for (String element: elements) {
+                for (String element : elements) {
                     row.put(fieldNames.get(column++), element);
                 }
                 csvSet.add(row);
@@ -72,35 +123,66 @@ public class CSVReaderWriter {
         }
         return csvSet;
     }
+*/
 
     static void placeCSVonStream(Set<Map<String, String>> data, OutputStream outputStream) {
         PrintStream writer = new PrintStream(outputStream);
         Set<String> fieldNames = null;
         int number_of_fields = 0;
-        for (Map<String, String> row: data) {
+        for (Map<String, String> row : data) {
             int field_number = 0;
             if (fieldNames == null) {
                 fieldNames = row.keySet();
                 number_of_fields = fieldNames.size();
-                for (String field: fieldNames) {
+                for (String field : fieldNames) {
                     writer.print(field);
-                    writer.print(++field_number<number_of_fields ? "," : "\n");
+                    writer.print(++field_number < number_of_fields ? "," : "\n");
                 }
             }
             field_number = 0;
-            for (String field: fieldNames) {
+            for (String field : fieldNames) {
                 String value = row.get(field);
                 writer.print(value != null ? value : "");
-                writer.print(++field_number<number_of_fields ? "," : "\n");
+                writer.print(++field_number < number_of_fields ? "," : "\n");
             }
         }
     }
 
+    /*
+        public static void main(String[] args) {
+            Set<Map<String, String>> demo = readCSV("demo.csv");
+            boolean success = writeCSV("out.csv", demo);
+            System.out.println(success ? "Wrote file!" : "Didn't write file");
+        }
+    */
 /*
     public static void main(String[] args) {
-        Set<Map<String, String>> demo = readCSV("demo.csv");
-        boolean success = writeCSV("out.csv", demo);
-        System.out.println(success ? "Wrote file!" : "Didn't write file");
+        Set<Map<String,String>> students = readCSV("students.csv");
+        for (Map<String,String> student: students) {
+            System.out.println(student.get("Name"));
+        }
+    }
+*//*
+    public static void main(String[] args) {
+        Set<Map<String, String>> courses = readCSV("courses.csv");
+        for (Map<String, String> course : courses) {
+            String foo = course.get("URL");
+            if (foo == null) {
+                foo = "Null object";
+            } else if (foo.equals("")) foo = "Empty String";
+            System.out.println(course.get("CourseID") + " " + course.get("Section") + " " + foo + " " + course.get(
+                    "Prerequisite1"));
+        }
+    }*/
+    public static void main(String[] args) {
+        Set<Map<String, String>> courses = readCSV("empty.csv");
+        for (Map<String, String> course : courses) {
+            String foo = course.get("URL");
+            if (foo == null) {
+                foo = "Null object";
+            } else if (foo.equals("")) foo = "Empty String";
+            System.out.println(course.get("CourseID") + " " + course.get("Section") + " " + foo + " " + course.get(
+                    "Prerequisite1"));
+        }
     }
-*/
 }
diff --git a/src/main/resources/csv/empty.csv b/src/main/resources/csv/empty.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/test/java/edu/unl/cse/csv_io/CSVReaderWriterTest.java b/src/test/java/edu/unl/cse/csv_io/CSVReaderWriterTest.java
index 5b8641b2475ff8ae3dbef6303d849dc75158bb17..12e27b653371350ea56e1a19523203106f8f567e 100644
--- a/src/test/java/edu/unl/cse/csv_io/CSVReaderWriterTest.java
+++ b/src/test/java/edu/unl/cse/csv_io/CSVReaderWriterTest.java
@@ -10,6 +10,7 @@ import java.util.*;
 import static org.junit.Assert.*;
 import static org.hamcrest.CoreMatchers.*;
 
+@SuppressWarnings("unchecked") // pee-yew!
 public class CSVReaderWriterTest {
     private static InputStream inputStream;
     private static OutputStream outputStream;
@@ -58,11 +59,12 @@ public class CSVReaderWriterTest {
         Set<String> expectedKeys = new HashSet<>(Arrays.asList(headers));
         // Oracle -- Rows
         Map<String, String> expectedRow = new HashMap<>();
-        for (int i=0; i<headers.length; i++) {
+        for (int i = 0; i < headers.length; i++) {
             expectedRow.put(headers[i], row[i]);
         }
         // Compare
-        Map<String,String> aRow = (Map<String,String>)result.toArray()[0];
+       assertNotNull(result);
+        Map<String, String> aRow = (Map<String, String>) result.toArray()[0];
         assertEquals(expectedKeys, aRow.keySet());
         assertTrue(result.contains(expectedRow));
     }
@@ -86,21 +88,22 @@ public class CSVReaderWriterTest {
         // Oracle -- Rows
         Map<String, String>[] expectedRows = new Map[2];
         for (int i = 0; i < expectedRows.length; i++) {
-            expectedRows[i] = new HashMap<String, String>();
+            expectedRows[i] = new HashMap<>();
             for (int j = 0; j < headers.length; j++) {
                 expectedRows[i].put(headers[j], rows[i][j]);
             }
         }
         // Compare
+        assertNotNull(result);
         Map<String, String> aRow = (Map<String, String>) result.toArray()[0];
         assertEquals(expectedKeys, aRow.keySet());
-        for (Map<String, String> expectedRow: expectedRows) {
+        for (Map<String, String> expectedRow : expectedRows) {
             assertTrue(result.contains(expectedRow));
         }
     }
 
     @Test
-    public void testParsingCSVwithOnlyHeaderRow() {
+    public void testParsingCSVWithOnlyHeaderRow() {
         // Input
         String[] headers = {"header1", "header2"};
         String[][] data = {headers};
@@ -146,7 +149,7 @@ public class CSVReaderWriterTest {
         String[] headers = {"header1", "header2"};
         String[][] rows = {{"datum1", "datum2"}, {"datum3", "datum4"}};
         Map<String, String>[] inputRows = new Map[2];
-        for (int i=0; i<inputRows.length; i++) {
+        for (int i = 0; i < inputRows.length; i++) {
             inputRows[i] = new HashMap<>(2);
             inputRows[i].put(headers[0], rows[i][0]);
             inputRows[i].put(headers[1], rows[i][1]);