         return lhs.uuid == rhs.uuid
     }
 }
+
+extension Array where Element == Encodable.Properties {
+    func decode<T:Encodable>(type: T.Type) -> [T] {
+        return flatMap{ T($0) }
+    }
+}
+
+extension Array where Element : Encodable {
+    func encode() -> [Encodable.Properties] {
+        return map{ $0.encode() }
+    }
+}

            self.uuid = uuid
            self.name = name ?? nameForWellKnownUuid(uuid)
        }
    }

    public struct CharacteristicSubscription {
        public let id: Identifier
        public let discoverDescriptors: Bool


            self.id = id
            self.discoverDescriptors = discoverDescriptors
        }

        public init?(_ properties: Encodable.Properties?) {
            guard let properties = properties else { return nil }

            if  let id = Identifier(properties["id"] as? Encodable.Properties),
                let discover = properties["discover"] as? Bool {
                self.id = id
                self.discoverDescriptors = discover
            } else {
                return nil
            }
        }
        
        public func encode() -> Encodable.Properties {
            return ["id": id.encode(), "discover": discoverDescriptors]
        }
    }

    public struct ServiceSubscription : Encodable {
        public let id: Identifier
        public var characteristics: [CharacteristicSubscription] // If empty then all of the service's characteristics and descriptors will be discovered
        
        public init(id: Identifier, characteristics: [CharacteristicSubscription] = []) {
            self.id = id
            self.characteristics = characteristics
        }

        public init?(_ properties: Encodable.Properties?) {
            guard let properties = properties else { return nil }

            if  let id = Identifier(properties["id"] as? Encodable.Properties),
                let characteristics = properties["characteristics"] as? [Encodable.Properties] {
                self.id = id
                self.characteristics = characteristics.decode(type: CharacteristicSubscription.self)
            } else {
                return nil
            }
        }
        
        public func encode() -> Encodable.Properties {
            return ["id": id.encode(), "characteristics": characteristics.encode()]
        }

        subscript(characteristicId: CBUUID) -> CharacteristicSubscription? {
