// Path: copybook4java/src/main/java/com/nordea/oss/copybook/converters/TypeConverter.java
// public interface TypeConverter {
//     void initialize(TypeConverterConfig config);
//     void validate(Class<?> type, int size, int decimals);
//     TypeConverter copy(Class<?> type) throws IllegalAccessException, InstantiationException;
//     Object to(byte[] bytes, int offset, int length, int decimals, boolean removePadding);
//     byte[] from(Object value, int length, int decimals, boolean addPadding);
// }
// 
// Path: copybook4java/src/main/java/com/nordea/oss/copybook/converters/TypeConverterConfig.java
// public class TypeConverterConfig {
//     private Charset charset;
//     private CopyBookFieldSigningType signingType;
//     private boolean rightPadding;
//     private char paddingChar;
//     private char nullFillerChar;
//     private String defaultValue;
//     private String format;
// 
//     public TypeConverterConfig() {
//     }
// 
//     public Charset getCharset() {
//         return charset;
//     }
// 
//     public void setCharset(Charset charset) {
//         this.charset = charset;
//     }
// 
//     public CopyBookFieldSigningType getSigningType() {
//         return signingType;
//     }
// 
//     public void setSigningType(CopyBookFieldSigningType signingType) {
//         this.signingType = signingType;
//     }
// 
//     public boolean isRightPadding() {
//         return rightPadding;
//     }
// 
//     public void setRightPadding(boolean rightPadding) {
//         this.rightPadding = rightPadding;
//     }
// 
//     public char getPaddingChar() {
//         return paddingChar;
//     }
// 
//     public void setPaddingChar(char paddingChar) {
//         this.paddingChar = paddingChar;
//     }
// 
//     public char getNullFillerChar() {
//         return nullFillerChar;
//     }
// 
//     public void setNullFillerChar(char nullFillerChar) {
//         this.nullFillerChar = nullFillerChar;
//     }
// 
//     public String getDefaultValue() {
//         return defaultValue;
//     }
// 
//     public void setDefaultValue(String defaultValue) {
//         this.defaultValue = defaultValue;
//     }
// 
//     public String getFormat() {
//         return format;
//     }
// 
//     public void setFormat(String format) {
//         this.format = format;
//     }
// }
// 
// Path: copybook4java/src/main/java/com/nordea/oss/copybook/exceptions/CopyBookException.java
// public class CopyBookException extends RuntimeException {
//     private static final long serialVersionUID = 28118369047109260L;
//     public CopyBookException(String message) {
//         super(message);
//     }
// 
//     public CopyBookException(String message, TypeConverterException ex) {
//         super(message + ": " + ex.getClass().getSimpleName() + " :" + ex.getMessage());
//     }
// 
//     public CopyBookException(String message, Exception ex) {
//         super(message + ": " + ex.getClass().getSimpleName() + " :" + ex.getMessage());
//     }
// }
// 
// Path: copybook4java/src/main/java/com/nordea/oss/copybook/exceptions/TypeConverterException.java
// public class TypeConverterException extends RuntimeException {
//     private static final long serialVersionUID = -7577535992947276304L;
//     public TypeConverterException(String message) {
//         super(message);
//     }
// }


import com.nordea.oss.copybook.annotations.*;
import com.nordea.oss.copybook.converters.TypeConverter;
import com.nordea.oss.copybook.converters.TypeConverterConfig;
import com.nordea.oss.copybook.exceptions.CopyBookException;
import com.nordea.oss.copybook.exceptions.TypeConverterException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
    }

    public CopyBookParser(Class<?> type, boolean debug) {
        // Read copybook annotations and defaults
        List<CopyBook> copybookAnnotations = getAnnotationsRecursively(CopyBookDefaults.class, CopyBook.class);
        copybookAnnotations.addAll(getAnnotationsRecursively(type, CopyBook.class));
        for(CopyBook annotation : copybookAnnotations) {
            if (!annotation.type().equals(CopyBookMapper.class)) {
                this.serializerClass = annotation.type();
            }
            if (!annotation.charset().isEmpty()) {
                config.setCharset(Charset.forName(annotation.charset()));
            }
            if(annotation.separatorChar() != 'G') { // Java sucks and does not support null as default value for annotations so we pick large G as this is å in EBCDIC and unlikely to be used as separator char
                config.setSeparatorByte((byte)annotation.separatorChar());
            }
            if(annotation.bitmapBlockSize() != 0) {
                config.setBitmapBlockSize(annotation.bitmapBlockSize());
            }
            if(annotation.strict()) {
                config.setStrict(annotation.strict());
            }
        }

        if(serializerClass == null) {
            throw new CopyBookException("Serialization class missing");
        }

        config.setDebug(debug);

// Path: copybook4java/src/main/java/com/nordea/oss/copybook/converters/TypeConverter.java
// public interface TypeConverter {
//     void initialize(TypeConverterConfig config);
//     void validate(Class<?> type, int size, int decimals);
//     TypeConverter copy(Class<?> type) throws IllegalAccessException, InstantiationException;
//     Object to(byte[] bytes, int offset, int length, int decimals, boolean removePadding);
//     byte[] from(Object value, int length, int decimals, boolean addPadding);
// }
// 
// Path: copybook4java/src/main/java/com/nordea/oss/copybook/converters/TypeConverterConfig.java
// public class TypeConverterConfig {
//     private Charset charset;
//     private CopyBookFieldSigningType signingType;
//     private boolean rightPadding;
//     private char paddingChar;
//     private char nullFillerChar;
//     private String defaultValue;
//     private String format;
// 
//     public TypeConverterConfig() {
//     }
// 
//     public Charset getCharset() {
//         return charset;
//     }
// 
//     public void setCharset(Charset charset) {
//         this.charset = charset;
//     }
// 
//     public CopyBookFieldSigningType getSigningType() {
//         return signingType;
//     }
// 
//     public void setSigningType(CopyBookFieldSigningType signingType) {
//         this.signingType = signingType;
//     }
// 
//     public boolean isRightPadding() {
//         return rightPadding;
//     }
// 
//     public void setRightPadding(boolean rightPadding) {
//         this.rightPadding = rightPadding;
//     }
// 
//     public char getPaddingChar() {
//         return paddingChar;
//     }
// 
//     public void setPaddingChar(char paddingChar) {
//         this.paddingChar = paddingChar;
//     }
// 
//     public char getNullFillerChar() {
//         return nullFillerChar;
//     }
// 
//     public void setNullFillerChar(char nullFillerChar) {
//         this.nullFillerChar = nullFillerChar;
//     }
// 
//     public String getDefaultValue() {
//         return defaultValue;
//     }
// 
//     public void setDefaultValue(String defaultValue) {
//         this.defaultValue = defaultValue;
//     }
// 
//     public String getFormat() {
//         return format;
//     }
// 
//     public void setFormat(String format) {
//         this.format = format;
//     }
// }
// 
// Path: copybook4java/src/main/java/com/nordea/oss/copybook/exceptions/CopyBookException.java
// public class CopyBookException extends RuntimeException {
//     private static final long serialVersionUID = 28118369047109260L;
//     public CopyBookException(String message) {
//         super(message);
//     }
// 
//     public CopyBookException(String message, TypeConverterException ex) {
//         super(message + ": " + ex.getClass().getSimpleName() + " :" + ex.getMessage());
//     }
// 
//     public CopyBookException(String message, Exception ex) {
//         super(message + ": " + ex.getClass().getSimpleName() + " :" + ex.getMessage());
//     }
// }
// 
// Path: copybook4java/src/main/java/com/nordea/oss/copybook/exceptions/TypeConverterException.java
// public class TypeConverterException extends RuntimeException {
//     private static final long serialVersionUID = -7577535992947276304L;
//     public TypeConverterException(String message) {
//         super(message);
//     }
// }


// Path: copybook4java/src/main/java/com/nordea/oss/copybook/serializers/CopyBookParser.java
import com.nordea.oss.copybook.annotations.*;
import com.nordea.oss.copybook.converters.TypeConverter;
import com.nordea.oss.copybook.converters.TypeConverterConfig;
import com.nordea.oss.copybook.exceptions.CopyBookException;
import com.nordea.oss.copybook.exceptions.TypeConverterException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

    }

    public CopyBookParser(Class<?> type, boolean debug) {
        // Read copybook annotations and defaults
        List<CopyBook> copybookAnnotations = getAnnotationsRecursively(CopyBookDefaults.class, CopyBook.class);
        copybookAnnotations.addAll(getAnnotationsRecursively(type, CopyBook.class));
        for(CopyBook annotation : copybookAnnotations) {
            if (!annotation.type().equals(CopyBookMapper.class)) {
                this.serializerClass = annotation.type();
            }
            if (!annotation.charset().isEmpty()) {
                config.setCharset(Charset.forName(annotation.charset()));
            }
            if(annotation.separatorChar() != 'G') { // Java sucks and does not support null as default value for annotations so we pick large G as this is å in EBCDIC and unlikely to be used as separator char
                config.setSeparatorByte((byte)annotation.separatorChar());
            }
            if(annotation.bitmapBlockSize() != 0) {
                config.setBitmapBlockSize(annotation.bitmapBlockSize());
            }
            if(annotation.strict()) {
                config.setStrict(annotation.strict());
            }
        }

        if(serializerClass == null) {
            throw new CopyBookException("Serialization class missing");
        }

        config.setDebug(debug);

        Map<String,TypeConverter> defaultTypeConverterMap = getTypeConvertersRecursively(CopyBookDefaults.class, config.getCharset(), config.isStrict());