public void ProcessStatusUpdateMessage(StatusUpdateMessage message, IPAddress address)
        {
            // is this request from myself?
            bool isLoopback = appInfo.InstanceHash.Hash.Equals(message.InstanceHash);

            var endPoint = new IPEndPoint(address, message.ServicePort);

            // register peers
            IEnumerable <PeerUpdateInfo> discoveredPeers = (message.KnownPeers ?? new DiscoveryPeerData[0])
                                                           .Select(kp => new PeerUpdateInfo(kp.ServiceEndpoint, PeerDiscoveryMode.OtherPeerDiscovery, clock.ConvertToLocal(message.Clock, kp.LastSuccessCommunication))) // peers known to peer we're communicating with
                                                           .Concat(new[] { new PeerUpdateInfo(endPoint, PeerDiscoveryMode.DirectDiscovery, clock.Time) });                                                               // direct peer we're communicating with

            peerRegistry.UpdatePeers(discoveredPeers);
            if (!peerRegistry.TryGetPeer(endPoint, out PeerInfo peer))
            {
                throw new InvalidOperationException($"Can't find peer in internal registry: {endPoint}");
            }

            // don't process requests from myself
            if (peer.IsLoopback)
            {
                return;
            }

            // update known packages if different
            peer.ReplaceKnownPackages(message.KnownPackages ?? Array.Empty <PackageStatus>());

            // register discovered packages
            if (message.KnownPackages?.Any() == true)
            {
                packageRegistry.RegisterDiscoveredPackages(message.KnownPackages.Select(kp => new DiscoveredPackage(endPoint, kp.Meta)));
            }

            // mark peer have new information
            OnPeerStatusUpdateSuccess(peer);
        }