/**
  * Get the port of the current STUN server.
  *
  * @return the port of the STUN server
  */
 public int getCurrentServerPort() {
   if (!currentServer.isNull()) {
     return currentServer.getPort();
   } else {
     return 0;
   }
 }
 /**
  * Get the name of the current STUN server.
  *
  * @return the name of the STUN server
  */
 public String getCurrentServerName() {
   if (!currentServer.isNull()) {
     return currentServer.getHostname();
   } else {
     return null;
   }
 }
  /**
   * Initialize the resolver.
   *
   * @throws XMPPException
   */
  @Override
  public void initialize() throws XMPPException {
    LOGGER.debug("Initialized");
    if (!isResolving() && !isResolved()) {
      // Get the best STUN server available
      if (currentServer.isNull()) {
        loadSTUNServers();
      }
      // We should have a valid STUN server by now...
      if (!currentServer.isNull()) {

        clearCandidates();

        resolverThread =
            new Thread(
                new Runnable() {
                  @Override
                  public void run() {
                    // Iterate through the list of interfaces, and ask
                    // to the STUN server for our address.
                    try {
                      final Enumeration ifaces = NetworkInterface.getNetworkInterfaces();
                      String candAddress;
                      int candPort;

                      while (ifaces.hasMoreElements()) {

                        final NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
                        final Enumeration iaddresses = iface.getInetAddresses();

                        while (iaddresses.hasMoreElements()) {
                          final InetAddress iaddress = (InetAddress) iaddresses.nextElement();
                          if (!iaddress.isLoopbackAddress() && !iaddress.isLinkLocalAddress()) {

                            // Reset the candidate
                            candAddress = null;
                            candPort = -1;

                            final DiscoveryTest test =
                                new DiscoveryTest(
                                    iaddress, currentServer.getHostname(), currentServer.getPort());
                            try {
                              // Run the tests and get the
                              // discovery
                              // information, where all the
                              // info is stored...
                              final DiscoveryInfo di = test.test();

                              candAddress =
                                  di.getPublicIP() != null
                                      ? di.getPublicIP().getHostAddress()
                                      : null;

                              // Get a valid port
                              if (defaultPort == 0) {
                                candPort = getFreePort();
                              } else {
                                candPort = defaultPort;
                              }

                              // If we have a valid candidate,
                              // add it to the list.
                              if (candAddress != null && candPort >= 0) {
                                final TransportCandidate candidate =
                                    new TransportCandidate.Fixed(candAddress, candPort);
                                candidate.setLocalIp(
                                    iaddress.getHostAddress() != null
                                        ? iaddress.getHostAddress()
                                        : iaddress.getHostName());
                                addCandidate(candidate);

                                resolvedPublicIP = candidate.getIp();
                                resolvedLocalIP = candidate.getLocalIp();
                                return;
                              }
                            } catch (final Exception e) {
                              LOGGER.error(e.getMessage(), e);
                            }
                          }
                        }
                      }
                    } catch (final SocketException e) {
                      LOGGER.error(e.getMessage(), e);
                    } finally {
                      setInitialized();
                    }
                  }
                },
                "Waiting for all the transport candidates checks...");

        resolverThread.setName("STUN resolver");
        resolverThread.start();
      } else {
        throw new IllegalStateException("No valid STUN server found.");
      }
    }
  }