// Path: fixb/src/main/java/org/fixb/FixException.java
// public class FixException extends RuntimeException {
//     private static final long serialVersionUID = 1;
// 
//     /**
//      * @param tag the field tag that has not been found
//      * @param fixMessage the FIX message that does not contain the tag
//      * @return an instance of FixException for a field-not-found case.
//      */
//     public static FixException fieldNotFound(int tag, String fixMessage) {
//         return new FixException("Field [" + tag + "] was not found in message: " + fixMessage);
//     }
// 
//     /**
//      * @param message the exception message
//      * @param cause the exception cause
//      */
//     public FixException(final String message, final Throwable cause) {
//         super(message, cause);
//     }
// 
//     /**
//      * @param cause the exception cause
//      */
//     public FixException(final Throwable cause) {
//         super(cause.getMessage(), cause);
//     }
// 
//     /**
//      * @param message the exception message
//      */
//     public FixException(final String message) {
//         super(message);
//     }
// }
// 
// Path: fixb/src/main/java/org/fixb/FixFieldExtractor.java
// public interface FixFieldExtractor<M> {
// 
//     /**
//      * Reads a tag of the FIX field identified by the given tag. If optional is true then in case of not found field
//      * null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage a FIX message object
//      * @param type       a type to return
//      * @param tag        a FIX field tag to read the tag from
//      * @param optional   determines whether a not found field should generate an exception
//      * @param <T>        the type of the result
//      * @throws FixException
//      */
//     <T> T getFieldValue(M fixMessage, Class<T> type, int tag, boolean optional);
// 
//     /**
//      * Reads all repeating groups from the given FIX message identified by the given tag. If optional is true then in
//      * case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage  the FIX message object
//      * @param type        the collection type to return
//      * @param groupTag    the FIX group tag to read from
//      * @param elementType type of the resulting collection elements (has the same meaning as the type parameter in
//      *                    getFieldValue)
//      * @param elementTag  the group delimiter tag (or the tag of a single element)
//      * @param optional    determines whether a not found group should generate an exception
//      * @param <T>         type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              Class<T> elementType,
//                                              int elementTag,
//                                              boolean optional);
// 
//     /**
//      * Reads all repeating block groups from the given FIX message identified by the given tag. If optional is true
//      * then in case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage    the FIX message object
//      * @param type          the collection type to return
//      * @param groupTag      the FIX group tag to read from
//      * @param componentMeta the FIX mapping metadata for a single repeating group
//      * @param optional      determines whether a not found group should generate an exception
//      * @param <T>           type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              FixBlockMeta<T> componentMeta,
//                                              boolean optional);
// }
// 
// Path: fixb/src/main/java/org/fixb/impl/CollectionFactory.java
// public class CollectionFactory {
//     /**
//      * Creates an empty instance of the given collection type.
//      * If the given an class in an interface, an ArrayList will be created for java.util.List
//      * or java.util.Collection interfaces, and HashSet for java.util.Set interface.
//      */
//     @SuppressWarnings("unchecked")
//     public static <T extends Collection<?>> T createCollection(Class<T> collClass) {
//         if (!collClass.isInterface() && !Modifier.isAbstract(collClass.getModifiers())) {
//             try {
//                 return collClass.newInstance();
//             } catch (InstantiationException | IllegalAccessException e) {
//                 throw new FixException(e.getMessage(), e);
//             }
//         } else if (List.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else if (Set.class.isAssignableFrom(collClass)) {
//             return (T) new HashSet<>();
//         } else if (Collection.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else {
//             throw new IllegalArgumentException("Unknown collection type: " + collClass);
//         }
//     }
// }


import org.fixb.FixException;
import org.fixb.FixFieldExtractor;
import org.fixb.impl.CollectionFactory;
import org.fixb.meta.*;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormatterBuilder;
import quickfix.*;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
                                        (Class<Collection<Object>>) groupMeta.getType(),
                                        groupMeta.getTag(),
                                        (FixMessageMeta<Object>) groupMeta.getComponentMeta());
                            }
                        } else {
                            fieldValue = getFieldValueFromMap(group, f.getType(), f.getTag());
                        }
                        values.put(f, fieldValue);
                    }
                }
                result.add(componentMeta.createModel(values));
            }
            return result;
        } catch (Exception e) {
            throw new FixException(e.getMessage(), e);
        }
    }

    private <T, C extends Collection<T>> C getGroupsFromMap(FieldMap fieldMap,
                                                            Class<C> type,
                                                            int tag,
                                                            Class<T> elementType,
                                                            int elementTag) {
        try {
            final C result = CollectionFactory.createCollection(type);
            for (Group group : fieldMap.getGroups(tag)) {
                result.add(getFieldValueFromMap(group, elementType, elementTag));
            }
            return result;
        } catch (Exception e) {
// Path: fixb/src/main/java/org/fixb/FixException.java
// public class FixException extends RuntimeException {
//     private static final long serialVersionUID = 1;
// 
//     /**
//      * @param tag the field tag that has not been found
//      * @param fixMessage the FIX message that does not contain the tag
//      * @return an instance of FixException for a field-not-found case.
//      */
//     public static FixException fieldNotFound(int tag, String fixMessage) {
//         return new FixException("Field [" + tag + "] was not found in message: " + fixMessage);
//     }
// 
//     /**
//      * @param message the exception message
//      * @param cause the exception cause
//      */
//     public FixException(final String message, final Throwable cause) {
//         super(message, cause);
//     }
// 
//     /**
//      * @param cause the exception cause
//      */
//     public FixException(final Throwable cause) {
//         super(cause.getMessage(), cause);
//     }
// 
//     /**
//      * @param message the exception message
//      */
//     public FixException(final String message) {
//         super(message);
//     }
// }
// 
// Path: fixb/src/main/java/org/fixb/FixFieldExtractor.java
// public interface FixFieldExtractor<M> {
// 
//     /**
//      * Reads a tag of the FIX field identified by the given tag. If optional is true then in case of not found field
//      * null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage a FIX message object
//      * @param type       a type to return
//      * @param tag        a FIX field tag to read the tag from
//      * @param optional   determines whether a not found field should generate an exception
//      * @param <T>        the type of the result
//      * @throws FixException
//      */
//     <T> T getFieldValue(M fixMessage, Class<T> type, int tag, boolean optional);
// 
//     /**
//      * Reads all repeating groups from the given FIX message identified by the given tag. If optional is true then in
//      * case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage  the FIX message object
//      * @param type        the collection type to return
//      * @param groupTag    the FIX group tag to read from
//      * @param elementType type of the resulting collection elements (has the same meaning as the type parameter in
//      *                    getFieldValue)
//      * @param elementTag  the group delimiter tag (or the tag of a single element)
//      * @param optional    determines whether a not found group should generate an exception
//      * @param <T>         type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              Class<T> elementType,
//                                              int elementTag,
//                                              boolean optional);
// 
//     /**
//      * Reads all repeating block groups from the given FIX message identified by the given tag. If optional is true
//      * then in case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage    the FIX message object
//      * @param type          the collection type to return
//      * @param groupTag      the FIX group tag to read from
//      * @param componentMeta the FIX mapping metadata for a single repeating group
//      * @param optional      determines whether a not found group should generate an exception
//      * @param <T>           type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              FixBlockMeta<T> componentMeta,
//                                              boolean optional);
// }
// 
// Path: fixb/src/main/java/org/fixb/impl/CollectionFactory.java
// public class CollectionFactory {
//     /**
//      * Creates an empty instance of the given collection type.
//      * If the given an class in an interface, an ArrayList will be created for java.util.List
//      * or java.util.Collection interfaces, and HashSet for java.util.Set interface.
//      */
//     @SuppressWarnings("unchecked")
//     public static <T extends Collection<?>> T createCollection(Class<T> collClass) {
//         if (!collClass.isInterface() && !Modifier.isAbstract(collClass.getModifiers())) {
//             try {
//                 return collClass.newInstance();
//             } catch (InstantiationException | IllegalAccessException e) {
//                 throw new FixException(e.getMessage(), e);
//             }
//         } else if (List.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else if (Set.class.isAssignableFrom(collClass)) {
//             return (T) new HashSet<>();
//         } else if (Collection.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else {
//             throw new IllegalArgumentException("Unknown collection type: " + collClass);
//         }
//     }
// }


// Path: fixb-quickfix/src/main/java/org/fixb/quickfix/QuickFixFieldExtractor.java
import org.fixb.FixException;
import org.fixb.FixFieldExtractor;
import org.fixb.impl.CollectionFactory;
import org.fixb.meta.*;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormatterBuilder;
import quickfix.*;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

                                        (Class<Collection<Object>>) groupMeta.getType(),
                                        groupMeta.getTag(),
                                        (FixMessageMeta<Object>) groupMeta.getComponentMeta());
                            }
                        } else {
                            fieldValue = getFieldValueFromMap(group, f.getType(), f.getTag());
                        }
                        values.put(f, fieldValue);
                    }
                }
                result.add(componentMeta.createModel(values));
            }
            return result;
        } catch (Exception e) {
            throw new FixException(e.getMessage(), e);
        }
    }

    private <T, C extends Collection<T>> C getGroupsFromMap(FieldMap fieldMap,
                                                            Class<C> type,
                                                            int tag,
                                                            Class<T> elementType,
                                                            int elementTag) {
        try {
            final C result = CollectionFactory.createCollection(type);
            for (Group group : fieldMap.getGroups(tag)) {
                result.add(getFieldValueFromMap(group, elementType, elementTag));
            }
            return result;
        } catch (Exception e) {
            throw new FixException(e.getMessage(), e);