/// <summary> Creates a new SockIO obj for the given server.
        /// 
        /// If server fails to connect, then return null and do not try<br/>
        /// again until a duration has passed.  This duration will grow<br/>
        /// by doubling after each failed attempt to connect. 
        /// </summary>
        /// 
        /// <param name="host">host:port to connect to</param>
        /// <returns>SockIO obj or null if failed to create</returns>
        private SockIO CreateSocket(string host)
        {
            SockIO socket = null;

            // if host is dead, then we don't need to try again
            // until the dead status has expired
            if (hostDead.Contains(host) && hostDeadDur.Contains(host))
            {
                DateTime store = (DateTime) hostDead[host];
                long expire = ((long) hostDeadDur[host]);

                if ((store.Ticks + expire) > (DateTime.Now.Ticks - 621355968000000000) / 10000)
                    return null;
            }

            try
            {
                socket = new SockIO(host, this.socketTO, this.nagle);

                if (!socket.Connected)
                {
                    if(log.IsErrorEnabled) log.Error("failed to get SockIO obj for: " + host + " -- new socket is not connected");
                    try
                    {
                        socket.TrueClose();
                    }
                    catch(Exception ex)
                    {
                        if(log.IsErrorEnabled) log.Error("failed to close SockIO obj for server: " + host, ex);

                        socket = null;
                    }
                }
            }
            catch(Exception ex)
            {
                if(log.IsErrorEnabled) log.Error("failed to get SockIO obj for: " + host, ex);
            }

            // if we failed to get socket, then mark
            // host dead for a duration which falls off
            if (socket == null)
            {
                DateTime now = DateTime.Now;
                hostDead.Add(host, now);
                long expire = (hostDeadDur.Contains(host))?((long) ((long) hostDeadDur[host]) * 2):1000;
                hostDeadDur.Add(host, (long) expire);
                if(log.IsDebugEnabled) log.Debug("Ignoring dead host: " + host + " for " + expire + " ms");

                // also clear all entries for this host from availPool
                ClearHostFromPool(availPool, host);
            }
            else
            {
                if(log.IsDebugEnabled) log.Debug("Created socket (" + socket.GetHashCode() + ") for host: " + host);
                hostDead.Remove(host);
                hostDeadDur.Remove(host);
            }

            return socket;
        }
        /// <summary>
        /// Checks a SockIO object in with the pool.
        /// 
        /// This will remove SocketIO from busy pool, and optionally<br/>
        /// add to avail pool.
        /// </summary>
        /// 
        /// <param name="socket">socket to return</param>
        /// <param name="addToAvail">add to avail pool if true</param>
        public virtual void CheckIn(SockIO socket, bool addToAvail)
        {
            lock (this)
            {

                string host = socket.Host;
                if(log.IsDebugEnabled) log.Debug("calling check-in on socket: " + socket.GetHashCode() + " for host: " + host);

                // remove from the busy pool
                if(log.IsDebugEnabled) log.Debug("removing socket (" + socket.GetHashCode() + ") from busy pool for host: " + host);
                RemoveSocketFromPool(busyPool, host, socket);

                // add to avail pool
                if (addToAvail && socket.Connected)
                {
                    if(log.IsDebugEnabled) log.Debug("returning socket (" + socket.GetHashCode() + " to avail pool for host: " + host);
                    AddSocketToPool(availPool, host, socket);
                }
            }
        }