     case continuation
     case text
     case binary
-//    case nonControl(NonControlFrame)
+    case nonControlExtension(NonControlFrameExtension)
     case connectionClose
     case ping
     case pong
-//    case control(ControlFrame)
+    case controlExtension(ControlFrameExtension)
 
     // 4 bytes
     init(_ i: Byte) throws {

        case 0xA:
            self = .pong
        case 0xb...0xf: // reserved control frame
//            let cf = try ControlFrame(i)
//            self = .control(cf)
            throw Error.invalid
        default:
            throw Error.invalid
        }
    }
}


    public func containsMask(_ mask: Self) -> Bool {
        return (self & mask) == mask
    }
}

/*
 Reserved bits:
 
 
 The protocol is designed to allow for extensions, which will add
 capabilities to the base protocol.  The endpoints of a connection
 MUST negotiate the use of any extensions during the opening
 handshake.  This specification provides opcodes 0x3 through 0x7 and
 0xB through 0xF, the "Extension data" field, and the frame-rsv1,
 frame-rsv2, and frame-rsv3 bits of the frame header for use by
 extensions.  The negotiation of extensions is discussed in further
 detail in Section 9.1.  Below are some anticipated uses of
 extensions.  This list is neither complete nor prescriptive.

 o  "Extension data" may be placed in the "Payload data" before the
 "Application data".

 o  Reserved bits can be allocated for per-frame needs.

 o  Reserved opcode values can be defined.

 o  Reserved bits can be allocated to the opcode field if more opcode
 values are needed.

 o  A reserved bit or an "extension" opcode can be defined that
 allocates additional bits out of the "Payload data" to define
 larger opcodes or more per-frame bits.
 */