                 ctx.fireChannelRead(self.wrapInboundOut(frame))
             case .continueParsing:
                 do {
-                    try self.validateState()
+                    try self.parser.validateState(maxFrameSize: self.maxFrameSize)
                 } catch {
                     self.handleError(error, ctx: ctx)
                 }

/// This parser attempts to parse a websocket frame incrementally, keeping as much parsing state around as possible to ensure that
/// we don't repeatedly partially parse the data.
struct WSParser {
    internal private(set) var firstByte: UInt8? = nil
    internal private(set) var length: Int? = nil
    internal private(set) var masked: Bool = false
    internal private(set) var maskingKey: WebSocketMaskingKey? = nil

    /// The current state of the decoder during incremental parse.
    var state: DecoderState = .idle

    private mutating func reset() {
        self.state = .idle
        self.firstByte = nil
        self.length = nil
        self.masked = false
        self.maskingKey = nil
    }

    mutating func parseStep(_ buffer: inout ByteBuffer) -> ParseResult {
        switch self.state {
        case .idle:
            // This is a new buffer. We want to find the first octet and save it off.
            assert(self.firstByte == nil)
            guard let firstByte = buffer.readInteger(as: UInt8.self) else {
                return .insufficientData
            }
            self.firstByte = firstByte
            self.state = .firstByteReceived
            return .continueParsing

        case .firstByteReceived:
            // Now we're looking for the length. We begin by finding the length byte to see if we
            // need any more data.
            assert(self.length == nil)
            assert(self.firstByte != nil)
            guard let lengthByte = buffer.readInteger(as: UInt8.self) else {
                return .insufficientData
            }

            self.masked = (lengthByte & 0x80) != 0

            switch lengthByte & 0x7F {
            case 126:
                self.state = .waitingForLengthWord
            case 127:
                self.state = .waitingForLengthQWord
            case let len:
                assert(len <= 125)
                self.length = Int(len)
                self.state = self.masked ? .waitingForMask : .waitingForData
            }
            return .continueParsing

        case .waitingForLengthWord:
            // We've got a one-word length here.
            assert(self.length == nil)
            assert(self.firstByte != nil)
            guard let lengthWord = buffer.readInteger(as: UInt16.self) else {
                return .insufficientData
            }

            self.length = Int(lengthWord)
            self.state = self.masked ? .waitingForMask : .waitingForData
            return .continueParsing

        case .waitingForLengthQWord:
            // We've got a qword of length here.
            assert(self.length == nil)
            assert(self.firstByte != nil)
            guard let lengthQWord = buffer.readInteger(as: UInt64.self) else {
                return .insufficientData
            }

            self.length = Int(lengthQWord)
            self.state = self.masked ? .waitingForMask : .waitingForData
            return .continueParsing

        case .waitingForMask:
            // We're waiting for the masking key.
            assert(maskingKey == nil)
            assert(self.firstByte != nil)
            assert(self.length != nil)
            guard let maskingKey = buffer.readInteger(as: UInt32.self) else {
                return .insufficientData
            }
            self.maskingKey = WebSocketMaskingKey(networkRepresentation: maskingKey)
            self.state = .waitingForData
            return .continueParsing

        case .waitingForData:
            assert(self.firstByte != nil)
            assert(self.length != nil)
            guard let data = buffer.readSlice(length: self.length!) else {
                return .insufficientData
            }

            let frame = WebSocketFrame(firstByte: self.firstByte!, maskKey: self.maskingKey, applicationData: data)
            self.reset()
            return .result(frame)
        }
    }
}

        return .needMoreData
    }



    /// We hit a decoding error, we're going to tear things down now. To do this we're
    /// basically going to send an error frame and then close the connection. Once we're
