 }
 
 @objc open class BPPeer: NSObject {
-    open var displayName: String = ""
+    open var displayName: String = "" // is HHService.name !
     open var socket: GCDAsyncSocket?
     open var role: RoleType = .unknown
     open var state: BPPeerState = .notConnected
     open var IP: String = ""
+    var resolvedAddressInfos: [HHAddressInfo] = []
     override open func isEqual(_ object: Any?) -> Bool {
         if let rhs = object as? BPPeer {
-            return self.IP == rhs.IP
+            return self.displayName == rhs.displayName
         } else {
             return false
         }
     }
     override open var hash: Int {
-        return self.IP.hash
-//        let acceptableChars = NSCharacterSet.init(charactersInString: "1234567890")
-//        var str = "1" + IP
-//        str = String(str.characters.filter { acceptableChars.containsCharacter($0) })
-//        return Int.init(str)!
+        return self.displayName.hash
     }
     open var keepaliveTimer: Timer?
     open var lastReceivedOrSentData: Date = Date.init(timeIntervalSince1970: 0)

            return
        }
        
        NSLog("BluepeerObject: serviceDidResolve type: \(service.type), name: \(service.name), role: \(roleStr)")
        
        guard let delegate = self.sessionDelegate else {
            NSLog("BluepeerObject: WARNING, ignoring resolved service because sessionDelegate is not set")
            return
        }
        
        guard let hhaddresses: [HHAddressInfo] = service.resolvedAddressInfo else {
            NSLog("BluepeerObject: serviceDidResolve IGNORING service because could not get resolvedAddressInfo")
            return
        }
        
        // assume en0 is wifi, and use the first address that is NOT that if we are bluetooth only
        var wifiDevice: HHAddressInfo? = nil
        var nonWifiDevice: HHAddressInfo? = nil
        
        for thisAddress in hhaddresses {
            if (wifiDevice != nil && nonWifiDevice != nil) {
                NSLog("BluepeerObject: WARNING, found three or more devices. Just using the first two...")
                break
            }
            if (thisAddress.interfaceName == "en0") {
                wifiDevice = thisAddress
            } else {
                nonWifiDevice = thisAddress
            }
        }
        
        if (wifiDevice == nil && nonWifiDevice == nil) {
            NSLog("BluepeerObject: ERROR, found no devices/addresses!")
            return
        }
        
        var device: HHAddressInfo
        if (wifiDevice == nil) {
            NSLog("BluepeerObject: WARNING, did not find wifi device en0!")
            device = nonWifiDevice!
        } else if (nonWifiDevice == nil) {
            if (self.overBluetoothOnly) {
                NSLog("BluepeerObject: WARNING, found no non-wifi device and bluetoothOnly was specified -- doing nothing!")
                return
            }
            device = wifiDevice!
        } else {
            if (self.overBluetoothOnly) {
                device = nonWifiDevice!
            } else {
                device = wifiDevice!
            }
        }
        
        let newPeer = BPPeer.init()
        newPeer.role = role
        newPeer.displayName = service.name
        
        let ipAndPort = device.addressAndPortString
        guard let lastColonIndex = ipAndPort.range(of: ":", options: .backwards)?.lowerBound else {
            NSLog("ERROR: unexpected return of IP address with port")
            assert(false, "error")
            return
        }
        let ip = ipAndPort.substring(to: lastColonIndex)
        if ipAndPort.components(separatedBy: ":").count-1 > 1 {
            // ipv6 - looks like [00:22:22.....]:port
            newPeer.IP = ip.substring(with: Range(uncheckedBounds: (lower: ip.index(ip.startIndex, offsetBy: 1), upper: ip.index(ip.endIndex, offsetBy: -1))))
        } else {
            // ipv4 - looks like 10.1.2.3:port
            newPeer.IP = ip
        }
        NSLog("BluepeerObject: newPeer.IP being set to %@", newPeer.IP)
        self.addPeer(newPeer)
        
        self.dispatch_on_delegate_queue({
            delegate.browserFoundPeer?(role, peer: newPeer, inviteBlock: { (connect, timeoutForInvite) in
                self.stopBrowsing() // stop browsing once user has done something
                if connect {
                    do {
                        NSLog("... trying to connect...")
                        newPeer.socket = GCDAsyncSocket.init(delegate: self, delegateQueue: self.socketQueue)
                        newPeer.socket?.isIPv4PreferredOverIPv6 = false
                        newPeer.state = .connecting
                        let socketAddrData = Data.init(bytes: device.address, count: MemoryLayout<sockaddr>.size)
                        try newPeer.socket?.connect(toAddress: socketAddrData, viaInterface: device.interfaceName, withTimeout: timeoutForInvite)
                    } catch {
                        NSLog("BluepeerObject: could not connect.")
                    }
                } else {
                    NSLog("... got told NOT to connect.")
                    newPeer.state = .notConnected
                }
            })
        })
    }
    
    public func serviceDidNotResolve(_ service: HHService) {

            return
        }
        
        guard let txtdata = service.txtData else {
            NSLog("BluepeerObject: serviceDidResolve IGNORING service because no txtData found")
            return
