protected ProxyConnection(ConnectionInfo connectionInfo)
        {
            Ensure.That(connectionInfo, "connectionInfo").IsNotNull();

            HttpClient = CreateHttpClient(connectionInfo);
            IsDisposed = false;
        }
        static void MainAsync(string[] args)
        {
            // Display banner
            Console.WriteLine("╔═══════════════════════════════════════╗");
            Console.WriteLine("║         taskwatcher for ADAI          ║");
            Console.WriteLine("╚═══════════════════════════════════════╝");
            Console.WriteLine();

            // Collect credentials
            Console.Write("Enter username for " + DB + ": ");
            username = Console.ReadLine();
            Console.Write("Enter password (hidden): ");
            password = GetPassword();

            // Compose connection string
            connString = "Data Source=" + DB + "; User Id=" + username + "; Password="******"http://www.zeropumpkin.iriscouch.com/taskwatcher-fmb"))
            {
                // Connection never times out, since we use a continuous change feed
                Timeout = TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite)
            };

            //MyCouchClientBootstrapper bootstrapper = new MyCouchClientBootstrapper();
            //bootstrapper.DbConnectionFn = new Func<ConnectionInfo, IDbConnection>(ProxyDbConnection);

            using (MyCouchClient couch = new MyCouchClient(connInfo))
            {
                Console.Write("Checking remote DB...");

                // Create the database if it does not exist
                couch.Database.PutAsync().Wait();

                Task<DocumentHeaderResponse> headTask = couch.Documents.HeadAsync("_design/tasks");
                headTask.Wait();

                // Create design document with tasks view
                if (!headTask.Result.IsSuccess)
                {
                    string taskDesignDoc = "{ \"language\": \"javascript\", \"views\": { \"tasks\": { \"map\": \"function(doc) { if (doc.$doctype != 'adaiTask') return; emit(doc._id, { 'rev': doc._rev }); }\" } } }";
                    couch.Documents.PutAsync("_design/tasks", taskDesignDoc).Wait();
                }

                Console.WriteLine("exists");

                //using (MyCouchStore store = new MyCouchStore(couch))
                //{
                //    while (true)
                //    {
                //        Console.Write("Enter task ID: ");
                //        string taskID = Console.ReadLine();

                //        //ADAITask t = await store.GetByIdAsync<ADAITask>(taskID);

                //        ADAITask t = new ADAITask(Int32.Parse(taskID));
                //        t.LastUpdated = DateTime.Now;

                //        Console.WriteLine("Storing doc...");
                //        Task<ADAITask> task = store.StoreAsync(t);
                //        task.Wait();
                //        Console.WriteLine("Doc stored: " + t._id);
                //    }
                //}

                //// First get the changes feed to get the last seq nr
                //GetChangesRequest getChangesRequest = new GetChangesRequest
                //{
                //    Feed = ChangesFeed.Normal
                //};

                //Task<ChangesResponse> changesTask = couch.Changes.GetAsync(getChangesRequest);
                //changesTask.Wait();
                //string lastSeqNr = changesTask.Result.LastSeq;

                // Start timer - callback is called immediately
                workTimer = new Timer(WorkTimerCallback, couch, 0, TIMER_PERIOD);

                //// Now start continuous observation using the last seq nr
                //getChangesRequest = new GetChangesRequest
                //{
                //    Feed = ChangesFeed.Continuous,
                //    Since = lastSeqNr
                //};
                //CancellationToken cancellationToken = new CancellationToken();
                //IObservable<string> changes = couch.Changes.ObserveContinuous(getChangesRequest, cancellationToken);

                //changeObserver = new ChangeObserver(workTimer, TIMER_PERIOD);
                //changes.Subscribe(changeObserver);
                //Debug.WriteLine("Started continuous observation, from seq nr " + lastSeqNr);

                while (true)
                {
                    // Do nothing
                }
            }
        }
        protected HttpClient CreateHttpClient(ConnectionInfo connectionInfo)
        {
            var handler = new HttpClientHandler
            {
                AllowAutoRedirect = false,
                Proxy = WebRequest.DefaultWebProxy,
                UseProxy = WebRequest.DefaultWebProxy.IsBypassed(connectionInfo.Address)
            };

            var client = new HttpClient(handler, true)
            {
                BaseAddress = new Uri(connectionInfo.GetAbsoluteAddressExceptUserInfo().TrimEnd(new[] { '/' }))
            };
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(HttpContentTypes.Json));

            if (connectionInfo.Timeout.HasValue)
                client.Timeout = connectionInfo.Timeout.Value;

            var basicAuthString = connectionInfo.GetBasicAuthString();
            if (basicAuthString != null)
            {
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicAuthString.Value);
            }

            return client;
        }
 static IDbConnection ProxyDbConnection(ConnectionInfo connInfo)
 {
     return new ProxyDbConnection(connInfo);
 }