public void putRendezvousServiceDescriptorToDirectory(TorConfig torConfig, Directory directory,
            final NetLayer torNetLayerToConnectToDirectoryService, HiddenServiceProperties hiddenServiceProps)
    throws IOException, TorException {
        // get the the z-part of the address/domain name
        final String hiddenServicePermanentIdBase32 = RendezvousServiceDescriptorUtil.calculateZFromPublicKey(hiddenServiceProps.getPublicKey());
        final Date now = new Date();
        final String PRE = "putRendezvousServiceDescriptorToDirectory(): ";
        

        // try to post the descriptors
        final AtomicInteger advertiseSuccess = new AtomicInteger(0);
        for (int replica=0; replica<RENDEZVOUS_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; replica++) {
            try {
                final RendezvousServiceDescriptor sd = new RendezvousServiceDescriptor(
                        hiddenServicePermanentIdBase32, replica, now,
                        hiddenServiceProps.getPublicKey(), hiddenServiceProps.getPrivateKey(), hiddenServiceProps.getIntroPoints());
                byte[] descriptorId = sd.getDescriptorId();
                final String descriptorIdBase32 = Encoding.toBase32(descriptorId);
                final String descriptorIdHex = Encoding.toHexStringNoColon(descriptorId);
                Fingerprint descriptorIdAsFingerprint = new FingerprintImpl(descriptorId);
                final int replicaFinal = replica;
                
                // try to post the descriptor to hidden service directory servers that are responsible for the descriptorId -
                // do it in parallel
                Collection<RouterImpl> routers = directory.getThreeHiddenDirectoryServersWithFingerpringGreaterThan(descriptorIdAsFingerprint);
                for (RouterImpl ro : routers) {
                    final RouterImpl r = ro;
                    new Thread() {
                        public void run() {
                            TcpipNetAddress dirAddress = r.getDirAddress();
                            dirAddress = new TcpipNetAddress(dirAddress.getHostnameOrIpaddress()+":"+dirAddress.getPort());
                            log.info(PRE+"try putting service descriptor for "
                                    + hiddenServicePermanentIdBase32 + " with descriptorID base32/hex="+ descriptorIdBase32+"/"+descriptorIdHex
                                    +" (with replica="+replicaFinal+") from " + r);
         
                            // try to post
                            for (int attempts=0; attempts<TorConfig.retriesConnect; attempts++) {
                                try {
                                    postServiceDescriptor(torNetLayerToConnectToDirectoryService, dirAddress, sd);
                                    advertiseSuccess.addAndGet(1);
                                    // finish thread
                                    return;
                                } catch (Exception e) {
                                    log.warning(PRE+"unable to connect to directory server " + dirAddress + "(" + e.getMessage() + ")");
                                    continue;
                                }
                            }
                        }
                    }.start();
                }
            } catch (TorException e1) {
                log.log(Level.WARNING, "unexpected exception", e1);
            }
        }
        
        // wait until timeout or at least one descriptor is posted
        final int TIMEOUT_SECONDS = 120;
        final int MIN_NUMBER_OF_ADVERTISEMENTS = 1;
        for (int seconds=0; seconds<TIMEOUT_SECONDS && advertiseSuccess.get()<MIN_NUMBER_OF_ADVERTISEMENTS; seconds++) {
            // wait a second
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) { /* do nothing */ }
        }
 
        // at least one advertisement?
        if (advertiseSuccess.get() < MIN_NUMBER_OF_ADVERTISEMENTS) {
            throw new TorException("RendezvousServiceDescriptorService: no successful hidden service descriptor advertisement");
        }
    }