         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


        }
    }

    public struct PeripheralSubscription : Encodable {
        public let name: String
        public var services: [ServiceSubscription] // If empty then all of the peripheral's services, characteristics and descriptors will be discovered
   
        public init(name: String, services: [ServiceSubscription] = []) {
            self.name = name
            self.services = services
        }
        
        public init?(_ properties: Encodable.Properties?) {
            guard let properties = properties else { return nil }
            
            if  let name = properties["name"] as? String,
                let services = properties["services"] as? [Encodable.Properties] {
                self.name = name
                self.services = services.decode(type: ServiceSubscription.self)
            } else {
                return nil
            }
        }
        
        public func encode() -> Encodable.Properties {
            return ["name": name, "services": services.encode()]
        }
        
        subscript(serviceId: CBUUID) -> ServiceSubscription? {
            let result = services.filter() { $0.id.uuid == serviceId }
            return result.count == 1 ? result[0] : nil
