private void InitializeLeanKitMonitoring()
		{
			try
			{
				var host = ConfigurationManager.AppSettings["LeanKit-AccountName"];
				var email = ConfigurationManager.AppSettings["LeanKit-EmailAddress"];
				var password = ConfigurationManager.AppSettings["LeanKit-Password"];
				var boardIds = ConfigurationManager.AppSettings["LeanKit-BoardId"];

				var leanKitAuth = new LeanKitAccountAuth
				{
					Hostname = host,
					Username = email,
					Password = password
				};

				var boardId = int.Parse(boardIds);

				_leanKitIntegration = new LeanKitIntegrationFactory().Create(boardId, leanKitAuth);
				_leanKitIntegration.BoardChanged += IntegrationOnBoardChanged;
				_leanKitIntegration.StartWatching();
			}
			catch (Exception ex)
			{
				ShowMessage("Error: " + ex.Message);
			}
		}
            internal BoardSubscription(LeanKitAccountAuth auth, long boardId)
            {
                _boardId = boardId;
				LkClientApi = new LeanKitClientFactory().Create(auth);
				Integration = new LeanKitIntegrationFactory().Create(_boardId, auth);

                new Thread(WatchThread).Start();
            }
            internal BoardSubscription(LeanKitAccountAuth auth, long boardId, int pollingFrequency)
            {
                _boardId = boardId;
				LkClientApi = new LeanKitClientFactory().Create(auth);
	            var settings = new IntegrationSettings {CheckForUpdatesIntervalSeconds = pollingFrequency};
	            Integration = new LeanKitIntegrationFactory().Create(_boardId, auth, settings);

                new Thread(WatchThread).Start();
            }
        public static LeanKitBasicAuth ToBasicAuth(this LeanKitAccountAuth accountAuth)
        {
            var auth = new LeanKitBasicAuth
            {
                Username            = accountAuth.Username,
                Password            = accountAuth.Password,
                Hostname            = accountAuth.Hostname,
                UrlTemplateOverride = accountAuth.UrlTemplateOverride
            };

            return(auth);
        }
        public ILeanKitApi Subscribe(LeanKitAccountAuth auth, long boardId, Action<long, BoardChangedEventArgs, ILeanKitApi> notification)
        {
            if (notification == null)
            {
                throw new Exception("Must provide subscription notification function");
            }
            lock (BoardSubscriptions)
            {
                if (!BoardSubscriptions.ContainsKey(boardId))
                {
	                BoardSubscriptions[boardId] = new BoardSubscription(auth, boardId);
                }
 
                BoardSubscriptions[boardId].Notifications.Add(notification);
                
                return BoardSubscriptions[boardId].LkClientApi;
            }
        }
		/// <summary>
		///     Factory method that creates and returns the <see cref="LeanKitIntegration" /> implementation using the
		///     LeanKitClient created with the default <see cref="IRestCommandProcessor" />.
		/// </summary>
		/// <remarks>
		///     The default implementation of the <see cref="IRestCommandProcessor" /> uses RestSharp.
		/// </remarks>
		/// <param name="boardId">The Identity of the Board that will be watched and modified.</param>
		/// <param name="accountAuth">The account authentication information used to connect to the LeanKit API.</param>
		/// <returns>The <see cref="ILeanKitIntegration" /> used to monitor and modify the specified board. </returns>
		public ILeanKitIntegration Create(long boardId, LeanKitAccountAuth accountAuth)
		{
			var clientFactory = new LeanKitClientFactory();
			var apiClient = clientFactory.Create(accountAuth);
			return new LeanKitIntegration(boardId, apiClient);
		}
		public ILeanKitApi Create(LeanKitAccountAuth accountAuth)
		{
			var leanKitClient = new LeanKitClient(new RestSharpCommandProcessor(new ValidationService(null), new IntegrationSettings()));
			return leanKitClient.Initialize(accountAuth);
		}
        protected override void OnStartFixture()
        {
            TestConfig = Test<Configuration>.Item;
            TestAuth = new LeanKitAccountAuth
            {
                Hostname = TestConfig.LeanKit.Url,
				UrlTemplateOverride = "http://{0}.leankit.com",
                Username = TestConfig.LeanKit.User,
                Password = TestConfig.LeanKit.Password
            };

        }
		private void SaveLogin(LeanKitAccountAuth account)
		{
			"Saving LeanKit login information...".Debug();

			try
			{
				var dir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
				if (dir == null) throw new Exception("Could not access current directory.");
				var curFolder = dir.FullName;
				var storagefile = Path.Combine(curFolder, "config-edit.json");
				var localStorage = new LocalStorage<Configuration>(storagefile);
				var config = File.Exists(storagefile) ? localStorage.Load() : new Configuration();

				config.LeanKit = new ServerConfiguration
				{
					Host = account.Hostname,
					User = account.Username,
					Password = account.Password
				};
				localStorage.Save(config);
			}
			catch (Exception ex)
			{
				string.Format("Error saving login creditials: {0}", ex.Message).Error(ex);
				throw;
			}
		}
		private ILeanKitApi Connect(Request request, bool saveLogin = false)
		{

			LeanKitClientFactory = new LeanKitClientFactory();
			var account = new LeanKitAccountAuth
				{
					Hostname = request.Host,
					Username = request.User,
					Password = request.Password,
					UrlTemplateOverride = request.Host
				};

			if (saveLogin) SaveLogin(account);

			// expand host if necessary
			if (account.Hostname == "kanban-cibuild")
				account.UrlTemplateOverride = "http://kanban-cibuild.localkanban.com/";
			else if (!account.Hostname.Contains("http://"))
				account.UrlTemplateOverride = "https://" + account.Hostname + ".leankit.com/";
			
			string.Format("Attempting connection to {0}", request).Debug();

			return LeanKitClientFactory.Create(account);

		}
		public ILeanKitApi Initialize(LeanKitAccountAuth accountAuth)
		{
			_accountAuth = accountAuth.ToBasicAuth();
			return this;
		}
		//TODO: would be great if we could reload configuration for just a single board
       
        private void ConnectToLeanKit()
        {
            LeanKitAccount = new LeanKitAccountAuth
            {
                Hostname = Configuration.LeanKit.Url,
                UrlTemplateOverride = GetTemplateOverride(Configuration.LeanKit.Url),
                Username = Configuration.LeanKit.User,
                Password = Configuration.LeanKit.Password
            };

            try
            {
				Log.Debug("Connecting to LeanKit account [{0}] with account [{1}]", LeanKitAccount.Hostname, LeanKitAccount.Username);
                LeanKit = LeanKitClientFactory.Create(LeanKitAccount);
            }
            catch (Exception ex)
            {
                Log.Error("Failed to open LeanKit API: " + ex.Message);
            }
        }
		public ILeanKitApi Initialize(LeanKitAccountAuth accountAuth)
		{
			_accountAuth = accountAuth;
			return this;
		}
		public void RunQuery()
		{
			ValidateQuery();

			var leanKitAuth = new LeanKitAccountAuth
			{
				Hostname = _args.Host,
				Username = _args.User,
				Password = _args.Password
			};

			// For internal development testing
			if (_args.Host.Equals("kanban-cibuild", StringComparison.InvariantCultureIgnoreCase)) 
				leanKitAuth.UrlTemplateOverride = "http://{0}.localkanban.com";

			WriteInfo("Connecting to LeanKit account...");
			var api = new LeanKitClientFactory().Create(leanKitAuth);

			if (_args.Boards)
			{
				WriteInfo("Getting all boards...");
				var boards = api.GetBoards();
				var boardList = boards.Select(Mapper.Map<BoardLiteView>);
				var output = _args.Csv ? boardList.ToCsv() : _args.Json ? boardList.ToJson() : boardList.Dump();
				Console.WriteLine(output);
			}
			else if (_args.Board > 0)
			{
				WriteInfo(string.Format("Getting board [{0}]...", _args.Board));
				var board = api.GetBoard(_args.Board);
				if (_args.Lanes || _args.Lane > 0 || _args.Cards)
				{
					// Get lanes
					var boardLanes = new List<Lane>();
					if (_args.Lane > 0)
					{
						WriteInfo(string.Format("Getting lane [{0}]...", _args.Lane));
						boardLanes.AddRange(board.AllLanes().Where(lane => lane.Id == _args.Lane));
					}
					else
					{
						if (_args.IncludeBacklog) boardLanes.AddRange(board.Backlog);
						boardLanes.AddRange(board.Lanes);
						if (_args.IncludeArchive) boardLanes.AddRange(board.Archive);
					}

					if (_args.Cards)
					{
						WriteInfo("Getting cards...");
						var cards = new List<MappedCardView>();
						foreach (var lane in boardLanes)
						{
							cards.AddRange(lane.Cards.Select(Mapper.Map<MappedCardView>));
						}
						// Archived cards is a separate API call
						if (_args.IncludeArchive)
						{
							var archivedCards = api.GetArchiveCards(_args.Board);
							cards.AddRange(archivedCards.Select(Mapper.Map<MappedCardView>));
						}
						var output = _args.Csv ? cards.ToCsv() : _args.Json ? cards.ToJson() : cards.Dump();
						Console.WriteLine(output);
					}
					else
					{
						var lanes = boardLanes.Select(Mapper.Map<LaneView>);
						var output = _args.Csv ? lanes.ToCsv() : _args.Json ? lanes.ToJson() : lanes.Dump();
						Console.WriteLine(output);
					}
				}
				else
				{
					var boardView = Mapper.Map<BoardView>(board);
					var output = _args.Csv ? boardView.ToCsv() : _args.Json ? boardView.ToJson() : boardView.Dump();
					Console.WriteLine(output);
				}
			}
		}