class AcceptorIoHandler extends AbstractIoHandler {

    @Override
    protected void processMessage(IoSession protocolSession, Message message) throws Exception {
        Session qfSession = (Session) protocolSession.getAttribute(SessionConnector.QF_SESSION);
        if (qfSession == null) {
            final Optional<String> msgTypeField = message.getHeader().getOptionalString(MsgType.FIELD);
            if (msgTypeField.isPresent() && msgTypeField.get().equals(MsgType.LOGON)) {
                final SessionID sessionID = MessageUtils.getReverseSessionID(message);
                qfSession = sessionProvider.getSession(sessionID, eventHandlingStrategy.getSessionConnector());
                if (qfSession != null) {
                    final Log sessionLog = qfSession.getLog();
                    Responder responder = qfSession.getResponder();
                    if (responder != null) {
                        // Session is already bound to another connection
                        sessionLog.onErrorEvent("Multiple logons/connections for this session are not allowed."
                                + " Closing connection from " + protocolSession.getRemoteAddress()
                                + " since session is already established from " + responder.getRemoteAddress());
                        protocolSession.closeNow();
                        return;
                    }
                    sessionLog.onEvent("Accepting session " + qfSession.getSessionID() + " from "
                            + protocolSession.getRemoteAddress());
                    final int heartbeatInterval = message.isSetField(HeartBtInt.FIELD) ? message.getInt(HeartBtInt.FIELD) : 0;
                    qfSession.setHeartBeatInterval(heartbeatInterval);
                    sessionLog.onEvent("Acceptor heartbeat set to " + heartbeatInterval
                            + " seconds");
                    protocolSession.setAttribute(SessionConnector.QF_SESSION, qfSession);
                    final NetworkingOptions networkingOptions = getNetworkingOptions();
                    qfSession.setResponder(new IoSessionResponder(protocolSession,
                            networkingOptions.getSynchronousWrites(), networkingOptions
                                    .getSynchronousWriteTimeout(), qfSession.getMaxScheduledWriteRequests()));
                    if (sessionID.isFIXT()) { // QFJ-592
                        if (message.isSetField(DefaultApplVerID.FIELD)) {
                            final ApplVerID applVerID = new ApplVerID(
                                    message.getString(DefaultApplVerID.FIELD));
                            qfSession.setTargetDefaultApplicationVersionID(applVerID);
                            sessionLog.onEvent("Setting DefaultApplVerID (" + DefaultApplVerID.FIELD + "="
                                    + applVerID.getValue() + ") from Logon");
                        }
                    }
                } else {
                    log.error("Unknown session ID during logon: {} cannot be found in session list {} (connecting from {} to {})",
                            sessionID,
                            eventHandlingStrategy.getSessionConnector().getSessions(),
                            protocolSession.getRemoteAddress(),
                            protocolSession.getLocalAddress());
                    return;
                }
            } else {
                log.warn("Ignoring non-logon message before session establishment: {}", message);
                protocolSession.closeNow();
                return;
            }
        }

        eventHandlingStrategy.onMessage(qfSession, message);
    }

    public  AcceptorIoHandler(AcceptorSessionProvider sessionProvider,
            NetworkingOptions networkingOptions, EventHandlingStrategy eventHandlingStrategy);

}