// Path: src/main/java/uk/elementarysoftware/quickcsv/api/ByteArraySource.java
// public interface ByteArraySource {
// 
//     ByteArrayChunk getNext() throws Exception;
//     
//     public abstract static class ReusableChunk {
// 
//         private final Runnable onFree;
//         private final AtomicInteger usageCount = new AtomicInteger(0);
//         
//         /**
//         * @param onFree - callback that will be called when usage count reaches zero
//         */
//         protected ReusableChunk(Runnable onFree) {
//             this.onFree = onFree;
//         }
//         
//         public void incrementUseCount() {
//             usageCount.incrementAndGet();
//         }
//         
//         public void decrementUseCount() {
//             int value = usageCount.decrementAndGet();
//             if (value <= 0) onFree.run();
//         }
//     }
//     
//     public static class ByteArrayChunk extends ReusableChunk {
//         public static final ByteArrayChunk EMPTY = new ByteArrayChunk(new byte[0], 0, false, (b) -> {});
//         
//         private final byte[] data;
//         private final int length;
//         private final boolean isLast;
// 
//         /**
//          * @param data - underlying content
//          * @param length - content length
//          * @param isLast - is this chunk of is last
//          * @param onFree - callback that will be called when data from this chunk has been fully consumed.
//          */
//         public ByteArrayChunk(byte[] data, int length, boolean isLast, Consumer<byte[]> onFree) {
//             super(() -> onFree.accept(data));
//             this.data = data;
//             this.length = length;
//             this.isLast = isLast;
//         }
// 
//         public byte[] getData() {
//             return data;
//         }
// 
//         public int getLength() {
//             return length;
//         }
// 
//         public boolean isLast() {
//             return isLast;
//         }
//     }
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/CSVParser.java
// public interface CSVParser<T> {
//     
//     public default Stream<T> parse(File file) throws IOException {
//         InputStream is = new FileInputStream(file);
//         return parse(is).onClose(() -> IOUtils.closeQuietly(is));
//     }
//     
//     public Stream<T> parse(InputStream is);
//     
//     public Stream<T> parse(ByteArraySource bas);
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/CSVRecord.java
// public interface CSVRecord {
//     public void skipField();
//     public void skipFields(int nFields);
//     
//     public Field getNextField();
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/Field.java
// public interface Field {
// 
//     public ByteBuffer raw();
// 
//     public String asString();
//     
//     public double asDouble();
//     public byte asByte();
//     public char asChar();
//     public short asShort();
//     public int asInt();
//     public long asLong();
//     
//     public Integer asBoxedInt();
//     public Double asBoxedDouble();
// 
//     public boolean isEmpty();
// 
//     public Field clone();
// }


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.util.function.Function;
import java.util.stream.Stream;
import uk.elementarysoftware.quickcsv.api.ByteArraySource;
import uk.elementarysoftware.quickcsv.api.CSVParser;
import uk.elementarysoftware.quickcsv.api.CSVRecord;
import uk.elementarysoftware.quickcsv.api.Field;
        };
    }

    public static class SimpleCSVRecord implements CSVRecord {

        private String[] fields;
        private int index;

        public SimpleCSVRecord(String[] fields) {
            this.index = 0;
            this.fields = fields;
        }

        @Override
        public void skipField() {
            index++;
        }

        @Override
        public void skipFields(int nFields) {
            index+=nFields;
        }

        @Override
        public Field getNextField() {
            return new SimpleField(fields[index++]);
        }

    }
    
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/ByteArraySource.java
// public interface ByteArraySource {
// 
//     ByteArrayChunk getNext() throws Exception;
//     
//     public abstract static class ReusableChunk {
// 
//         private final Runnable onFree;
//         private final AtomicInteger usageCount = new AtomicInteger(0);
//         
//         /**
//         * @param onFree - callback that will be called when usage count reaches zero
//         */
//         protected ReusableChunk(Runnable onFree) {
//             this.onFree = onFree;
//         }
//         
//         public void incrementUseCount() {
//             usageCount.incrementAndGet();
//         }
//         
//         public void decrementUseCount() {
//             int value = usageCount.decrementAndGet();
//             if (value <= 0) onFree.run();
//         }
//     }
//     
//     public static class ByteArrayChunk extends ReusableChunk {
//         public static final ByteArrayChunk EMPTY = new ByteArrayChunk(new byte[0], 0, false, (b) -> {});
//         
//         private final byte[] data;
//         private final int length;
//         private final boolean isLast;
// 
//         /**
//          * @param data - underlying content
//          * @param length - content length
//          * @param isLast - is this chunk of is last
//          * @param onFree - callback that will be called when data from this chunk has been fully consumed.
//          */
//         public ByteArrayChunk(byte[] data, int length, boolean isLast, Consumer<byte[]> onFree) {
//             super(() -> onFree.accept(data));
//             this.data = data;
//             this.length = length;
//             this.isLast = isLast;
//         }
// 
//         public byte[] getData() {
//             return data;
//         }
// 
//         public int getLength() {
//             return length;
//         }
// 
//         public boolean isLast() {
//             return isLast;
//         }
//     }
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/CSVParser.java
// public interface CSVParser<T> {
//     
//     public default Stream<T> parse(File file) throws IOException {
//         InputStream is = new FileInputStream(file);
//         return parse(is).onClose(() -> IOUtils.closeQuietly(is));
//     }
//     
//     public Stream<T> parse(InputStream is);
//     
//     public Stream<T> parse(ByteArraySource bas);
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/CSVRecord.java
// public interface CSVRecord {
//     public void skipField();
//     public void skipFields(int nFields);
//     
//     public Field getNextField();
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/Field.java
// public interface Field {
// 
//     public ByteBuffer raw();
// 
//     public String asString();
//     
//     public double asDouble();
//     public byte asByte();
//     public char asChar();
//     public short asShort();
//     public int asInt();
//     public long asLong();
//     
//     public Integer asBoxedInt();
//     public Double asBoxedDouble();
// 
//     public boolean isEmpty();
// 
//     public Field clone();
// }


// Path: src/test/java/uk/elementarysoftware/quickcsv/parser/simple/StraightForwardParser.java
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.util.function.Function;
import java.util.stream.Stream;
import uk.elementarysoftware.quickcsv.api.ByteArraySource;
import uk.elementarysoftware.quickcsv.api.CSVParser;
import uk.elementarysoftware.quickcsv.api.CSVRecord;
import uk.elementarysoftware.quickcsv.api.Field;

        };
    }

    public static class SimpleCSVRecord implements CSVRecord {

        private String[] fields;
        private int index;

        public SimpleCSVRecord(String[] fields) {
            this.index = 0;
            this.fields = fields;
        }

        @Override
        public void skipField() {
            index++;
        }

        @Override
        public void skipFields(int nFields) {
            index+=nFields;
        }

        @Override
        public Field getNextField() {
            return new SimpleField(fields[index++]);
        }

    }
    
    public static class SimpleField implements Field {