private void initICCC()
        {
            // The message to request the current listeners:
            var messageListeners = new ICCCGetListeners();
            var messageListenersData = ICCCProcessor.INSTANCE.convertMessage2Data(messageListeners);

            // The messagw to request the current hosts:
            var messageHosts = new ICCCGetHosts();
            var messageHostsData = ICCCProcessor.INSTANCE.convertMessage2Data(messageHosts);

            this.initialOceanServersLock.EnterReadLock();
            try
            {
                // An endless loop until we got the initial connection done:
                while(true)
                {
                    var chosenServer = "127.0.0.1:60000";
                    if(this.initialOceanServers.Count == 1)
                    {
                        // In case of only one, take that:
                        chosenServer = this.initialOceanServers[0];
                    }

                    if(this.initialOceanServers.Count > 1)
                    {
                        // Select a random server:
                        chosenServer = this.initialOceanServers[BetterRND.INSTANCE.nextInt(0, this.initialOceanServers.Count)];
                    }

                    //
                    // Build an listener regarding this server for the first message:
                    //
                    var tmpListener = new ICCCListener();
                    tmpListener.Channel = messageListeners.getChannel();
                    tmpListener.Command = messageListeners.getCommand();
                    tmpListener.IPAddressPort = chosenServer;
                    tmpListener.IsActive = true;
                    tmpListener.Kind = ICCCKind.KindOcean;

                    // Send the message:
                    var answerData = this.sendMessage(messageListenersData, tmpListener);

                    // Decode the answer:
                    var messageListenerAnswer = ICCCProcessor.INSTANCE.convertData2Message(answerData, messageListeners.getAnswerObject()) as ICCCGetListenersAnswer;

                    // Was the request successful?
                    if(messageListenerAnswer == null)
                    {
                        // No: Re-try!
                        Thread.Sleep(TimeSpan.FromSeconds(30));
                        continue;
                    }

                    // Store the listeners:
                    this.cacheLock.EnterWriteLock();
                    try
                    {
                        this.icccListenerCache.Clear();
                        var countEntries = messageListenerAnswer.Channels.Length;
                        for(var n = 0; n < countEntries; n++)
                        {
                            this.icccListenerCache.Add(new ICCCListener(messageListenerAnswer.Channels[n], messageListenerAnswer.Commands[n], messageListenerAnswer.IPAddressesPorts[n], true, messageListenerAnswer.Kinds[n]));
                        }
                    }
                    finally
                    {
                        this.cacheLock.ExitWriteLock();
                    }

                    //
                    // Build an listener regarding this server for the second message:
                    //
                    tmpListener = new ICCCListener();
                    tmpListener.Channel = messageHosts.getChannel();
                    tmpListener.Command = messageHosts.getCommand();
                    tmpListener.IPAddressPort = chosenServer;
                    tmpListener.IsActive = true;
                    tmpListener.Kind = ICCCKind.KindOcean;

                    // Send the message:
                    answerData = this.sendMessage(messageHostsData, tmpListener);

                    // Decode the answer:
                    var messageHostsAnswer = ICCCProcessor.INSTANCE.convertData2Message(answerData, messageHosts.getAnswerObject()) as ICCCGetHostsAnswer;

                    // Was the request successful?
                    if(messageHostsAnswer == null)
                    {
                        // No: Re-try!
                        Thread.Sleep(TimeSpan.FromSeconds(30));
                        continue;
                    }

                    // Store the hosts:
                    this.cacheLock.EnterWriteLock();
                    try
                    {
                        this.icccHostsCache.Clear();
                        var countEntries = messageHostsAnswer.Hostnames.Length;
                        for(var n = 0; n < countEntries; n++)
                        {
                            this.icccHostsCache.Add(new ICCCHost(messageHostsAnswer.Hostnames[n], messageHostsAnswer.IPAddressesPorts[n], messageHostsAnswer.Kinds[n]));
                        }
                    }
                    finally
                    {
                        this.cacheLock.ExitWriteLock();
                    }

                    break;
                }
            }
            finally
            {
                this.initialOceanServersLock.ExitReadLock();
            }
        }
        /// <summary>
        /// Sends the message to the wire. This method is thread-safe!
        /// </summary>
        /// <param name="data">The sending message's data.</param>
        /// <param name="listener">The receiving listener.</param>
        /// <returns>The answer's data.</returns>
        internal NameValueCollection sendMessage(NameValueCollection data, ICCCListener listener)
        {
            if(data == null || listener == null || data.Count < 2) // channel + command = 2
            {
                return new NameValueCollection();
            }

            try
            {
                // First of all, sign the message:
                data = ICCCProcessor.INSTANCE.signMessage(data);

                // Get a web client:
                using(var web = new WebClient())
                {
                    // Send the request / message to the wire and wait & read the answer:
                    var responseBytes = web.UploadValues(string.Format("http://{0}/ICCC", listener.IPAddressPort), data);

                    // Converts the answer's bytes to text:
                    var answerBody = ASCIIEncoding.UTF8.GetString(responseBytes);

                    // No answer?
                    if(answerBody == null || answerBody == string.Empty)
                    {
                        return new NameValueCollection();
                    }

                    // Convert the text to values:
                    return HttpUtility.ParseQueryString(answerBody);
                }
            }
            catch
            {
                return new NameValueCollection();
            }
        }