/// <summary>
        /// For synchronization with App.config or Web.configs.
        /// </summary>
        /// <param name="couchbaseClientSection"></param>
        internal ClientConfiguration(CouchbaseClientSection couchbaseClientSection)
        {
            UseSsl = couchbaseClientSection.UseSsl;
            SslPort = couchbaseClientSection.SslPort;
            ApiPort = couchbaseClientSection.ApiPort;
            DirectPort = couchbaseClientSection.DirectPort;
            MgmtPort = couchbaseClientSection.MgmtPort;
            HttpsMgmtPort = couchbaseClientSection.HttpsMgmtPort;
            HttpsApiPort = couchbaseClientSection.HttpsApiPort;
            ObserveInterval = couchbaseClientSection.ObserveInterval;
            ObserveTimeout = couchbaseClientSection.ObserveTimeout;
            MaxViewRetries = couchbaseClientSection.MaxViewRetries;
            ViewHardTimeout = couchbaseClientSection.ViewHardTimeout;
            SerializationContractResolver = new CamelCasePropertyNamesContractResolver();
            DeserializationContractResolver = new CamelCasePropertyNamesContractResolver();

            foreach (var server in couchbaseClientSection.Servers)
            {
                Servers.Add(((UriElement)server).Uri);
            }
            foreach (var bucketElement in couchbaseClientSection.Buckets)
            {
                var bucket = (BucketElement) bucketElement;
                var bucketConfiguration = new BucketConfiguration
                {
                    BucketName = bucket.Name,
                    UseSsl = bucket.UseSsl,
                    Password = bucket.Password,
                    ObserveInterval = bucket.ObserveInterval,
                    ObserveTimeout = bucket.ObserveTimeout,
                    PoolConfiguration = new PoolConfiguration
                    {
                        MaxSize = bucket.ConnectionPool.MaxSize,
                        MinSize = bucket.ConnectionPool.MinSize,
                        WaitTimeout = bucket.ConnectionPool.WaitTimeout,
                        ShutdownTimeout = bucket.ConnectionPool.ShutdownTimeout,
                        UseSsl = bucket.ConnectionPool.UseSsl, 
                    }
                };
                BucketConfigs = new Dictionary<string, BucketConfiguration> {{bucket.Name, bucketConfiguration}};
            }
        }
        /// <summary>
        /// For synchronization with App.config or Web.configs.
        /// </summary>
        /// <param name="section"></param>
        public ClientConfiguration(CouchbaseClientSection section)
        {
            Timer = TimingFactory.GetTimer(Log);
            NodeAvailableCheckInterval = section.NodeAvailableCheckInterval;
            UseSsl = section.UseSsl;
            SslPort = section.SslPort;
            ApiPort = section.ApiPort;
            DirectPort = section.DirectPort;
            MgmtPort = section.MgmtPort;
            HttpsMgmtPort = section.HttpsMgmtPort;
            HttpsApiPort = section.HttpsApiPort;
            ObserveInterval = section.ObserveInterval;
            ObserveTimeout = section.ObserveTimeout;
            MaxViewRetries = section.MaxViewRetries;
            ViewHardTimeout = section.ViewHardTimeout;
            SerializationSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
            DeserializationSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
            EnableConfigHeartBeat = section.EnableConfigHeartBeat;
            HeartbeatConfigInterval = section.HeartbeatConfigInterval;
            ViewRequestTimeout = section.ViewRequestTimeout;
            Expect100Continue = section.Expect100Continue;
            DefaultConnectionLimit = section.DefaultConnectionLimit;
            MaxServicePointIdleTime = section.MaxServicePointIdleTime;
            EnableOperationTiming = section.EnableOperationTiming;
            DefaultOperationLifespan = section.OperationLifespan;
            QueryRequestTimeout = section.QueryRequestTimeout;
            IOErrorCheckInterval = section.IOErrorCheckInterval;
            IOErrorThreshold = section.IOErrorThreshold;

            //transcoders, converters, and serializers...o mai.
            Serializer = SerializerFactory.GetSerializer(this, section.Serializer);
            Converter = ConverterFactory.GetConverter(section.Converter);
            Transcoder = TranscoderFactory.GetTranscoder(this, section.Transcoder);

            //to enable tcp keep-alives
            EnableTcpKeepAlives = section.EnableTcpKeepAlives;
            TcpKeepAliveInterval = section.TcpKeepAliveInterval;
            TcpKeepAliveTime = section.TcpKeepAliveTime;

            var keepAlivesChanged = EnableTcpKeepAlives != true ||
                                    TcpKeepAliveInterval != 1000 ||
                                    TcpKeepAliveTime != 2*60*60*1000;

            //the default ioservice - this should be refactored to come from the configsection
            IOServiceCreator = IOServiceFactory.GetFactory(section.IOService);

            //the default connection pool creator
            ConnectionPoolCreator = ConnectionPoolFactory.GetFactory(section.ConnectionPool);

            //The default sasl mechanism creator
            CreateSaslMechanism = SaslFactory.GetFactory();

            foreach (var server in section.Servers)
            {
                Servers.Add(((UriElement)server).Uri);
                _serversChanged = true;
            }

            PoolConfiguration = new PoolConfiguration
            {
                MaxSize = section.ConnectionPool.MaxSize,
                MinSize = section.ConnectionPool.MinSize,
                WaitTimeout = section.ConnectionPool.WaitTimeout,
                ShutdownTimeout = section.ConnectionPool.ShutdownTimeout,
                UseSsl = UseSsl ? UseSsl : section.ConnectionPool.UseSsl,
                BufferSize = section.ConnectionPool.BufferSize,
                BufferAllocator = (p) => new BufferAllocator(p.MaxSize * p.BufferSize, p.BufferSize),
                ConnectTimeout = section.ConnectionPool.ConnectTimeout,
                SendTimeout = section.ConnectionPool.SendTimeout,
                EnableTcpKeepAlives = keepAlivesChanged ? EnableTcpKeepAlives : section.ConnectionPool.EnableTcpKeepAlives,
                TcpKeepAliveInterval = keepAlivesChanged ? TcpKeepAliveInterval : section.ConnectionPool.TcpKeepAliveInterval,
                TcpKeepAliveTime = keepAlivesChanged ? TcpKeepAliveTime : section.ConnectionPool.TcpKeepAliveTime,
                CloseAttemptInterval = section.ConnectionPool.CloseAttemptInterval,
                MaxCloseAttempts = section.ConnectionPool.MaxCloseAttempts,
                ClientConfiguration = this
            };

            BucketConfigs = new Dictionary<string, BucketConfiguration>();
            foreach (var bucketElement in section.Buckets)
            {
                var bucket = (BucketElement)bucketElement;
                var bucketConfiguration = new BucketConfiguration
                {
                    BucketName = bucket.Name,
                    UseSsl = bucket.UseSsl,
                    Password = bucket.Password,
                    ObserveInterval = bucket.ObserveInterval,
                    DefaultOperationLifespan = bucket.OperationLifespan ??(uint) DefaultOperationLifespan,
                    ObserveTimeout = bucket.ObserveTimeout,
                    UseEnhancedDurability = bucket.UseEnhancedDurability
                };
                //Configuration properties (including elements) can not be null, but we can check if it was originally presnt in xml and skip it.
                //By skipping the bucket specific connection pool settings we allow inheritance from clien-wide connection pool settings.
                if (bucket.ConnectionPool.ElementInformation.IsPresent)
                {
                    bucketConfiguration.PoolConfiguration = new PoolConfiguration
                    {
                        MaxSize = bucket.ConnectionPool.MaxSize,
                        MinSize = bucket.ConnectionPool.MinSize,
                        WaitTimeout = bucket.ConnectionPool.WaitTimeout,
                        ShutdownTimeout = bucket.ConnectionPool.ShutdownTimeout,
                        UseSsl = bucket.ConnectionPool.UseSsl,
                        BufferSize = bucket.ConnectionPool.BufferSize,
                        BufferAllocator = (p) => new BufferAllocator(p.MaxSize*p.BufferSize, p.BufferSize),
                        ConnectTimeout = bucket.ConnectionPool.ConnectTimeout,
                        SendTimeout = bucket.ConnectionPool.SendTimeout,
                        EnableTcpKeepAlives =
                            keepAlivesChanged ? EnableTcpKeepAlives : bucket.ConnectionPool.EnableTcpKeepAlives,
                        TcpKeepAliveInterval =
                            keepAlivesChanged ? TcpKeepAliveInterval : bucket.ConnectionPool.TcpKeepAliveInterval,
                        TcpKeepAliveTime = keepAlivesChanged ? TcpKeepAliveTime : bucket.ConnectionPool.TcpKeepAliveTime,
                        CloseAttemptInterval = bucket.ConnectionPool.CloseAttemptInterval,
                        MaxCloseAttempts = bucket.ConnectionPool.MaxCloseAttempts,
                        UseEnhancedDurability = bucket.UseEnhancedDurability,
                        ClientConfiguration = this
                    };
                }
                else
                {
                    bucketConfiguration.PoolConfiguration = PoolConfiguration;
                }
                BucketConfigs.Add(bucket.Name, bucketConfiguration);
            }

            //Set back to default
            _operationLifespanChanged = false;
            _poolConfigurationChanged = false;
        }
        public static async Task<GrainStateCouchbaseDataManager> Initialize(CouchbaseClientSection configSection)
        {
            var instance = new GrainStateCouchbaseDataManager();
            var config = new ClientConfiguration(configSection);
            _cluster = new Cluster(config);


            var tcs = new TaskCompletionSource<IBucket>();
            Action initAction;
            if (configSection.Buckets.Count > 0)
            {
                var buckets = new BucketElement[configSection.Buckets.Count];
                configSection.Buckets.CopyTo(buckets, 0);

                var bucketSetting = buckets.First();
                initAction = () => { tcs.SetResult(_cluster.OpenBucket(bucketSetting.Name)); };
            }
            else
                initAction = () => { tcs.SetResult(_cluster.OpenBucket()); };

            WaitCallback initBucket = (state) =>
            {
                try { initAction(); }
                catch (Exception ex) { tcs.SetException(new Exception("GrainStateCouchbaseDataManager initialize exception", ex)); }
            };

            ThreadPool.QueueUserWorkItem(initBucket, null);

            instance._bucket = await tcs.Task;

            return instance;
        }
 /// <summary>
 /// For synchronization with App.config or Web.configs.
 /// </summary>
 /// <param name="section"></param>
 public ClientConfiguration(CouchbaseClientSection section)
     : this((ICouchbaseClientDefinition) section)
 {
 }