void IServerPool.Start()
        {
            // get the pool urls
            this.poolUrls = this.configuration.Urls.ToArray();
            if (this.poolUrls.Length == 0)
            {
                throw new InvalidOperationException("At least 1 pool url must be specified.");
            }

            this.configListener = new BucketConfigListener(this.poolUrls, this.configuration.Bucket, this.configuration.BucketPassword)
            {
                Timeout      = (int)this.configuration.SocketPool.ConnectionTimeout.TotalMilliseconds,
                DeadTimeout  = (int)this.configuration.SocketPool.DeadTimeout.TotalMilliseconds,
                RetryCount   = this.configuration.RetryCount,
                RetryTimeout = this.configuration.RetryTimeout
            };

            this.configListener.ClusterConfigChanged += this.InitNodes;

            // start blocks until the first NodeListChanged event is triggered
            this.configListener.Start();
        }
        void IDisposable.Dispose()
        {
            GC.SuppressFinalize(this);

            if (this.state != null && this.state != InternalState.Empty)
            {
                lock (this.DeadSync)
                {
                    if (this.state != null && this.state != InternalState.Empty)
                    {
                        var currentNodes = this.state.CurrentNodes;
                        this.state = null;

                        this.configListener.Stop();
                        this.configListener = null;

                        if (this.resurrectTimer != null)
                        {
                            using (this.resurrectTimer)
                                this.resurrectTimer.Change(Timeout.Infinite, Timeout.Infinite);
                        }

                        this.resurrectTimer = null;

                        // close the pools
                        if (currentNodes != null)
                        {
                            for (var i = 0; i < currentNodes.Length; i++)
                            {
                                currentNodes[i].Dispose();
                            }
                        }
                    }
                }
            }
        }
        void IDisposable.Dispose()
        {
            GC.SuppressFinalize(this);

            if (this.state != null)
                lock (this.DeadSync)
                {
                    if (this.state != null)
                    {
                        var currentNodes = this.state.CurrentNodes;
                        this.state = null;

                        this.configListener.Stop();
                        this.configListener = null;

                        if (this.resurrectTimer != null)
                            using (this.resurrectTimer)
                                this.resurrectTimer.Change(Timeout.Infinite, Timeout.Infinite);

                        this.resurrectTimer = null;

                        // close the pools
                        if (currentNodes != null)
                            for (var i = 0; i < currentNodes.Length; i++)
                                currentNodes[i].Dispose();
                    }
                }
        }
        void IServerPool.Start()
        {
            // get the pool urls
            this.poolUrls = this.configuration.Urls.ToArray();
            if (this.poolUrls.Length == 0)
                throw new InvalidOperationException("At least 1 pool url must be specified.");

            this.configListener = new BucketConfigListener(this.poolUrls, this.bucketName, this.configuration.Credentials)
            {
                Timeout = (int)this.configuration.SocketPool.ConnectionTimeout.TotalMilliseconds,
                DeadTimeout = (int)this.configuration.SocketPool.DeadTimeout.TotalMilliseconds,
                RetryCount = this.configuration.RetryCount,
                RetryTimeout = this.configuration.RetryTimeout
            };

            this.configListener.ClusterConfigChanged += this.InitNodes;

            // start blocks until the first NodeListChanged event is triggered
            this.configListener.Start();
        }