     }
 }
 
-enum CharacteristicInfoPermission: String {
-    case read
-    case write
-    case events
-}
-
-extension Array where Element == CharacteristicInfoPermission {
-    var arrayLiteral: String {
-        "[" + self.map { ".\($0)" }.joined(separator: ", ") + "]"
+struct CharacteristicInfoPermission: OptionSet, CustomStringConvertible {
+    let rawValue: Int
+
+    static let read = CharacteristicInfoPermission(rawValue: 2)
+    static let write = CharacteristicInfoPermission(rawValue: 4)
+    static let events = CharacteristicInfoPermission(rawValue: 1)
+
+    var description: String {
+        var permissions: [String] = []
+        if contains(.read) { permissions += [".read"] }
+        if contains(.write) { permissions += [".write"] }
+        if contains(.events) { permissions += [".events"] }
+        return "[" + permissions.joined(separator: ", ") + "]"
     }
 }

        }

        func defaultValue(_ characteristic: CharacteristicInfo) -> String {
            if characteristic.isReadable {
                if enumeratedCharacteristics.contains(characteristic.hkname) {
                    guard let defaultCase = defaultEnumCase[characteristic.hkname] else {
                        preconditionFailure("No default enum case for enum \(characteristic.hkname)")

            return name.parameterName()
        }

        // Decode plist
        guard let plist = NSDictionary(contentsOf: plistPath),
            let plistDict = plist["PlistDictionary"] as? NSDictionary,
            let assistantDict = plistDict["Assistant"] as? NSDictionary,
