/** Stop advertising the service. */
 public void stop() {
   log.debug("Stopping ZeroConfService {}", this.key());
   if (ZeroConfService.services().containsKey(this.key())) {
     ZeroConfService.netServices()
         .values()
         .stream()
         .forEach(
             (netService) -> {
               try {
                 try {
                   log.debug("Unregistering {} from {}", this.key(), netService.getInetAddress());
                   netService.unregisterService(
                       this.serviceInfos.get(netService.getInetAddress()));
                   this.serviceInfos.remove(netService.getInetAddress());
                   this.listeners
                       .stream()
                       .forEach(
                           (listener) -> {
                             listener.serviceUnpublished(
                                 new ZeroConfServiceEvent(this, netService));
                           });
                 } catch (NullPointerException ex) {
                   log.debug(
                       "{} already unregistered from {}", this.key(), netService.getInetAddress());
                 }
               } catch (IOException ex) {
                 log.error(
                     "Unable to stop ZeroConfService {}. {}",
                     this.key(),
                     ex.getLocalizedMessage());
               }
             });
     ZeroConfService.services().remove(key());
   }
 }
 private static void stopAll(final boolean close) {
   log.debug("Stopping all ZeroConfServices");
   ZeroConfService.netServices()
       .values()
       .stream()
       .forEach(
           (netService) -> {
             new Thread() {
               @Override
               public void run() {
                 netService.unregisterAllServices();
                 if (close) {
                   try {
                     netService.close();
                   } catch (IOException ex) {
                     log.debug("jmdns.close() returned IOException: {}", ex.getMessage());
                   }
                 }
               }
             }.start();
           });
   ZeroConfService.services().clear();
 }
 /**
  * Return the fully qualified domain name or "computer" if the system name cannot be determined.
  * This method uses the {@link javax.jmdns.JmDNS#getHostName()} method to get the name.
  *
  * @param address The {@link java.net.InetAddress} for the FQDN.
  * @return The fully qualified domain name.
  */
 public static String FQDN(InetAddress address) {
   return ZeroConfService.netServices().get(address).getHostName();
 }
 /** Start advertising the service. */
 public void publish() {
   if (!isPublished()) {
     ZeroConfService.services.put(this.key(), this);
     this.listeners
         .stream()
         .forEach(
             (listener) -> {
               listener.serviceQueued(new ZeroConfServiceEvent(this, null));
             });
     boolean useIPv4 =
         ProfileUtils.getPreferences(
                 ProfileManager.getDefault().getActiveProfile(), ZeroConfService.class, false)
             .getBoolean(ZeroConfService.IPv4, true);
     boolean useIPv6 =
         ProfileUtils.getPreferences(
                 ProfileManager.getDefault().getActiveProfile(), ZeroConfService.class, false)
             .getBoolean(ZeroConfService.IPv6, true);
     for (JmDNS netService : ZeroConfService.netServices().values()) {
       ZeroConfServiceEvent event;
       ServiceInfo info;
       try {
         if (netService.getInetAddress() instanceof Inet6Address && !useIPv6) {
           // Skip if address is IPv6 and should not be advertised on
           log.debug("Ignoring IPv6 address {}", netService.getInetAddress().getHostAddress());
           continue;
         }
         if (netService.getInetAddress() instanceof Inet4Address && !useIPv4) {
           // Skip if address is IPv4 and should not be advertised on
           log.debug("Ignoring IPv4 address {}", netService.getInetAddress().getHostAddress());
           continue;
         }
         try {
           log.debug(
               "Publishing ZeroConfService for '{}' on {}",
               key(),
               netService.getInetAddress().getHostAddress());
         } catch (IOException ex) {
           log.debug(
               "Publishing ZeroConfService for '{}' with IOException {}",
               key(),
               ex.getLocalizedMessage(),
               ex);
         }
         // JmDNS requires a 1-to-1 mapping of serviceInfo to InetAddress
         if (!this.serviceInfos.containsKey(netService.getInetAddress())) {
           try {
             info = this.serviceInfo();
             netService.registerService(info);
             log.debug(
                 "Register service '{}' on {} successful.",
                 this.key(),
                 netService.getInetAddress().getHostAddress());
           } catch (IllegalStateException ex) {
             // thrown if the reference serviceInfo object is in use
             try {
               log.debug(
                   "Initial attempt to register '{}' on {} failed.",
                   this.key(),
                   netService.getInetAddress().getHostAddress());
               info = this.addServiceInfo(netService);
               log.debug(
                   "Retrying register '{}' on {}.",
                   this.key(),
                   netService.getInetAddress().getHostAddress());
               netService.registerService(info);
             } catch (IllegalStateException ex1) {
               // thrown if service gets registered on interface by
               // the networkListener before this loop on interfaces
               // completes, so we only ensure a later notification
               // is not posted continuing to next interface in list
               log.debug(
                   "'{}' is already registered on {}.",
                   this.key(),
                   netService.getInetAddress().getHostAddress());
               continue;
             }
           }
         } else {
           log.debug(
               "skipping '{}' on {}, already in serviceInfos.",
               this.key(),
               netService.getInetAddress().getHostAddress());
         }
         event = new ZeroConfServiceEvent(this, netService);
       } catch (IOException ex) {
         log.error("Unable to publish service for '{}': {}", key(), ex.getMessage());
         continue;
       }
       this.listeners
           .stream()
           .forEach(
               (listener) -> {
                 listener.servicePublished(event);
               });
     }
   }
 }