// Path: core/src/main/java/fixio/fixprotocol/FixMessage.java
// public interface FixMessage {
// 
//     String FIX_4_0 = "FIX.4.0";
//     String FIX_4_1 = "FIX.4.1";
//     String FIX_4_2 = "FIX.4.2";
//     String FIX_4_3 = "FIX.4.3";
//     String FIX_4_4 = "FIX.4.4";
//     String FIX_5_0 = "FIXT.1.1";
// 
//     FixMessageHeader getHeader();
// 
//     List<FixMessageFragment> getBody();
// 
//     Integer getInt(int tagNum);
// 
//     Integer getInt(FieldType field);
// 
//     String getString(int tagNum);
// 
//     @SuppressWarnings("unchecked")
//     <T> T getValue(int tagNum);
// 
//     String getString(FieldType field);
// 
//     <T> T getValue(FieldType field);
// 
//     Character getChar(int tagNum);
// 
//     Character getChar(FieldType fieldType);
// 
//     String getMessageType();
// 
//     default FixMessageFragment getFirst(int tagNum) {
//         final List<FixMessageFragment> body = getBody();
//         for (int i = 0; i < body.size(); i++) {
//             FixMessageFragment item = body.get(i);
//             if (item.getTagNum() == tagNum) {
//                 return item;
//             }
//         }
//         return null;
//     }
// 
//     default List<FixMessageFragment> getAll(int tagNum) {
//         final List<FixMessageFragment> body = getBody();
//         List<FixMessageFragment> result = new ArrayList<>(8);
//         for (int i = 0; i < body.size(); i++) {
//             FixMessageFragment item = body.get(i);
//             if (item.getTagNum() == tagNum) {
//                 result.add(item);
//             }
//         }
//         return result;
//     }
// 
//     default FixMessageFragment getLast(int tagNum) {
//         final List<FixMessageFragment> body = getBody();
//         for (int i = body.size() - 1; i >= 0; i--) {
//             FixMessageFragment item = body.get(i);
//             if (item.getTagNum() == tagNum) {
//                 return item;
//             }
//         }
//         return null;
//     }
// 
// }
// 
// Path: core/src/main/java/fixio/fixprotocol/FixMessageBuilder.java
// public interface FixMessageBuilder extends FieldListBuilder<FixMessageBuilder> {
//     FixMessageHeader getHeader();
// 
//     void copyHeader(FixMessageHeader header);
// 
//     List<? extends FixMessageFragment> getBody();
// 
//     void copyBody(List<? extends FixMessageFragment> body);
// }
// 
// Path: core/src/main/java/fixio/validator/BusinessRejectException.java
// public class BusinessRejectException extends Exception {
// 
//     /**
//      * MsgSeqNum of rejected message
//      */
//     private final int refSeqNum;
// 
//     /**
//      * The MsgType of the FIX message being referenced.
//      */
//     private final String refMsgType;
// 
//     /**
//      * The value of the business-level "ID" field on the message being referenced.
//      * Required unless the corresponding ID field (see list above) was not specified.
//      */
//     private final int businessRejectReason;
// 
//     /**
//      * Where possible, message to explain reason for rejection.
//      */
//     private final String text;
// 
//     public BusinessRejectException(int refSeqNum, String refMsgType, int businessRejectReason, String text) {
//         super(text);
//         this.refSeqNum = refSeqNum;
//         this.refMsgType = refMsgType;
//         this.businessRejectReason = businessRejectReason;
//         this.text = text;
//     }
// 
//     public int getRefSeqNum() {
//         return refSeqNum;
//     }
// 
//     public String getRefMsgType() {
//         return refMsgType;
//     }
// 
//     public int getBusinessRejectReason() {
//         return businessRejectReason;
//     }
// 
//     public String getText() {
//         return text;
//     }
// }
// 
// Path: core/src/main/java/fixio/validator/FixMessageValidator.java
// public interface FixMessageValidator {
// 
//     void validate(ChannelHandlerContext ctx, FixMessage msg);
// }


import fixio.fixprotocol.FixMessage;
import fixio.fixprotocol.FixMessageBuilder;
import fixio.validator.BusinessRejectException;
import fixio.validator.FixMessageValidator;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.List;
/*
 * Copyright 2014 The FIX.io Project
 *
 * The FIX.io Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package fixio.handlers;



@ChannelHandler.Sharable
public class CompositeFixApplicationAdapter extends FixApplicationAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(CompositeFixApplicationAdapter.class);
    private final List<FixMessageHandler> handlers;
    private final List<FixMessageValidator> validators;

    public CompositeFixApplicationAdapter(List<FixMessageValidator> validators, List<FixMessageHandler> handlers) {
        assert (validators != null) : "FixMessageValidators expected";
        assert (handlers != null) : "FixMessageHandlers expected";
        this.validators = Collections.unmodifiableList(validators);
        this.handlers = Collections.unmodifiableList(handlers);
    }

    @Override
// Path: core/src/main/java/fixio/fixprotocol/FixMessage.java
// public interface FixMessage {
// 
//     String FIX_4_0 = "FIX.4.0";
//     String FIX_4_1 = "FIX.4.1";
//     String FIX_4_2 = "FIX.4.2";
//     String FIX_4_3 = "FIX.4.3";
//     String FIX_4_4 = "FIX.4.4";
//     String FIX_5_0 = "FIXT.1.1";
// 
//     FixMessageHeader getHeader();
// 
//     List<FixMessageFragment> getBody();
// 
//     Integer getInt(int tagNum);
// 
//     Integer getInt(FieldType field);
// 
//     String getString(int tagNum);
// 
//     @SuppressWarnings("unchecked")
//     <T> T getValue(int tagNum);
// 
//     String getString(FieldType field);
// 
//     <T> T getValue(FieldType field);
// 
//     Character getChar(int tagNum);
// 
//     Character getChar(FieldType fieldType);
// 
//     String getMessageType();
// 
//     default FixMessageFragment getFirst(int tagNum) {
//         final List<FixMessageFragment> body = getBody();
//         for (int i = 0; i < body.size(); i++) {
//             FixMessageFragment item = body.get(i);
//             if (item.getTagNum() == tagNum) {
//                 return item;
//             }
//         }
//         return null;
//     }
// 
//     default List<FixMessageFragment> getAll(int tagNum) {
//         final List<FixMessageFragment> body = getBody();
//         List<FixMessageFragment> result = new ArrayList<>(8);
//         for (int i = 0; i < body.size(); i++) {
//             FixMessageFragment item = body.get(i);
//             if (item.getTagNum() == tagNum) {
//                 result.add(item);
//             }
//         }
//         return result;
//     }
// 
//     default FixMessageFragment getLast(int tagNum) {
//         final List<FixMessageFragment> body = getBody();
//         for (int i = body.size() - 1; i >= 0; i--) {
//             FixMessageFragment item = body.get(i);
//             if (item.getTagNum() == tagNum) {
//                 return item;
//             }
//         }
//         return null;
//     }
// 
// }
// 
// Path: core/src/main/java/fixio/fixprotocol/FixMessageBuilder.java
// public interface FixMessageBuilder extends FieldListBuilder<FixMessageBuilder> {
//     FixMessageHeader getHeader();
// 
//     void copyHeader(FixMessageHeader header);
// 
//     List<? extends FixMessageFragment> getBody();
// 
//     void copyBody(List<? extends FixMessageFragment> body);
// }
// 
// Path: core/src/main/java/fixio/validator/BusinessRejectException.java
// public class BusinessRejectException extends Exception {
// 
//     /**
//      * MsgSeqNum of rejected message
//      */
//     private final int refSeqNum;
// 
//     /**
//      * The MsgType of the FIX message being referenced.
//      */
//     private final String refMsgType;
// 
//     /**
//      * The value of the business-level "ID" field on the message being referenced.
//      * Required unless the corresponding ID field (see list above) was not specified.
//      */
//     private final int businessRejectReason;
// 
//     /**
//      * Where possible, message to explain reason for rejection.
//      */
//     private final String text;
// 
//     public BusinessRejectException(int refSeqNum, String refMsgType, int businessRejectReason, String text) {
//         super(text);
//         this.refSeqNum = refSeqNum;
//         this.refMsgType = refMsgType;
//         this.businessRejectReason = businessRejectReason;
//         this.text = text;
//     }
// 
//     public int getRefSeqNum() {
//         return refSeqNum;
//     }
// 
//     public String getRefMsgType() {
//         return refMsgType;
//     }
// 
//     public int getBusinessRejectReason() {
//         return businessRejectReason;
//     }
// 
//     public String getText() {
//         return text;
//     }
// }
// 
// Path: core/src/main/java/fixio/validator/FixMessageValidator.java
// public interface FixMessageValidator {
// 
//     void validate(ChannelHandlerContext ctx, FixMessage msg);
// }


// Path: core/src/main/java/fixio/handlers/CompositeFixApplicationAdapter.java
import fixio.fixprotocol.FixMessage;
import fixio.fixprotocol.FixMessageBuilder;
import fixio.validator.BusinessRejectException;
import fixio.validator.FixMessageValidator;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.List;

/*
 * Copyright 2014 The FIX.io Project
 *
 * The FIX.io Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package fixio.handlers;



@ChannelHandler.Sharable
public class CompositeFixApplicationAdapter extends FixApplicationAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(CompositeFixApplicationAdapter.class);
    private final List<FixMessageHandler> handlers;
    private final List<FixMessageValidator> validators;

    public CompositeFixApplicationAdapter(List<FixMessageValidator> validators, List<FixMessageHandler> handlers) {
        assert (validators != null) : "FixMessageValidators expected";
        assert (handlers != null) : "FixMessageHandlers expected";
        this.validators = Collections.unmodifiableList(validators);
        this.handlers = Collections.unmodifiableList(handlers);
    }

    @Override
    public void onMessage(ChannelHandlerContext ctx, FixMessage msg, List<Object> out) throws BusinessRejectException {