docs: protected int discoverPeers() {
          // Don't hold the lock whilst doing peer discovery: it can take a long time and cause high API latency.
          checkState(!lock.isHeldByCurrentThread());
          int maxPeersToDiscoverCount = this.vMaxPeersToDiscoverCount;
          long peerDiscoveryTimeoutMillis = this.vPeerDiscoveryTimeoutMillis;
          final Stopwatch watch = Stopwatch.createStarted();
          final List<PeerAddress> addressList = Lists.newLinkedList();
          for (PeerDiscovery peerDiscovery : peerDiscoverers /* COW */) {
              InetSocketAddress[] addresses;
              try {
                  addresses = peerDiscovery.getPeers(requiredServices, peerDiscoveryTimeoutMillis, TimeUnit.MILLISECONDS);
              } catch (PeerDiscoveryException e) {
                  log.warn(e.getMessage());
                  continue;
              }
              for (InetSocketAddress address : addresses) addressList.add(new PeerAddress(params, address));
              if (addressList.size() >= maxPeersToDiscoverCount) break;
          }
          if (!addressList.isEmpty()) {
              for (PeerAddress address : addressList) {
                  addInactive(address);
              }
              final ImmutableSet<PeerAddress> peersDiscoveredSet = ImmutableSet.copyOf(addressList);
              for (final ListenerRegistration<PeerDiscoveredEventListener> registration : peerDiscoveredEventListeners /* COW */) {
                  registration.executor.execute(new Runnable() {
                      @Override
                      public void run() {
                          registration.listener.onPeersDiscovered(peersDiscoveredSet);
                      }
                  });
              }
          }
          watch.stop();
          log.info("Peer discovery took {} and returned {} items", watch, addressList.size());
          return addressList.size();
      }