public ReportBuildStateResponse ReportBuildState (WebServiceLogin login, DBWork work)
		{
			ReportBuildStateResponse response = new ReportBuildStateResponse ();

			using (DB db = new DB ()) {
				VerifyUserInRole (db, login, Roles.BuildBot, true);
				Logger.Log (2, "ReportBuildState, state: {0}, start time: {1}, end time: {2}", work.State, work.starttime, work.endtime);
				if (work.starttime > new DateTime (2000, 1, 1) && work.endtime < work.starttime) {
					// the issue here is that the server interprets the datetime as local time, while it's always as utc.
					try {
						using (IDbCommand cmd = db.CreateCommand ()) {
							cmd.CommandText = "SELECT starttime FROM Work WHERE id = " + work.id;
							work.starttime = (DateTime) cmd.ExecuteScalar ();
						}
					} catch (Exception ex) {
						Logger.Log ("ReportBuildState: Exception while fixing timezone data: {0}", ex.Message);
					}
				}
				work.Save (db);
				work.Reload (db);

				response.Work = work;

				DBRevisionWork rw = DBRevisionWork_Extensions.Create (db, work.revisionwork_id);
				bool was_completed = rw.completed;
				rw.UpdateState (db);
				if (!was_completed && rw.completed) {
					rw.endtime = DBRecord.DatabaseNow;
					rw.Save (db);
				}
				response.RevisionWorkCompleted = rw.completed;

				using (var cmd = db.CreateCommand ()) {
					cmd.CommandText = "UPDATE Lane SET changed_date = @date WHERE id = @id;";
					DB.CreateParameter (cmd, "date", DateTime.UtcNow);
					DB.CreateParameter (cmd, "id", rw.lane_id);
					cmd.ExecuteNonQuery ();
				}

				Notifications.Notify (work, rw);

				// Check if any other lane depends on this one
				if (response.RevisionWorkCompleted) {
					using (IDbCommand cmd = db.CreateCommand ()) {
						cmd.CommandText = "SELECT id FROM LaneDependency WHERE dependent_lane_id = @lane_id LIMIT 1;";
						DB.CreateParameter (cmd, "lane_id", rw.lane_id);

						object value = cmd.ExecuteScalar ();
						if (value != null && value.GetType () == typeof (int)) {
							// If so, run the scheduler
							MonkeyWrench.Scheduler.Scheduler.ExecuteSchedulerAsync (false);
						}
					}
				}

				return response;
			}
		}
		public ReportBuildStateResponse ReportBuildState (WebServiceLogin login, DBWork work)
		{
			ReportBuildStateResponse response = new ReportBuildStateResponse ();

			using (DB db = new DB ())
			using (var transaction = db.BeginTransaction ()) {
				VerifyUserInRole (db, login, Roles.BuildBot, true);
				log.DebugFormat ("ReportBuildState, state: {0}, start time: {1}, end time: {2}", work.State, work.starttime, work.endtime);
				if (work.starttime > new DateTime (2000, 1, 1) && work.endtime < work.starttime) {
					// the issue here is that the server interprets the datetime as local time, while it's always as utc.
					try {
						using (IDbCommand cmd = db.CreateCommand ()) {
							cmd.CommandText = "SELECT starttime FROM Work WHERE id = " + work.id;
							var value = cmd.ExecuteScalar ();
							if (value is DateTime)
								work.starttime = (DateTime) value;
						}
					} catch (Exception ex) {
						log.ErrorFormat ("ReportBuildState: Exception while fixing timezone data: {0}", ex);
					}
				}
				work.Save (db);
				work.Reload (db);

				response.Work = work;

				DBRevisionWork rw = DBRevisionWork_Extensions.Create (db, work.revisionwork_id);
				bool was_completed = rw.completed;
				rw.UpdateState (db);

				if (rw.startedtime == null) {
					rw.startedtime = work.starttime;
					rw.Save (db);
				}

				if (!was_completed && rw.completed) {
					rw.endtime = DBRecord.DatabaseNow;
					rw.Save (db);
				}

				Notifications.Notify (work, rw);

				if (!was_completed && rw.completed) {
					var notifyInfo = new GenericNotificationInfo ();
					notifyInfo.laneID = rw.lane_id;
					notifyInfo.hostID = rw.host_id;
					notifyInfo.revisionID = rw.revision_id;
					notifyInfo.message = "Completed";
					notifyInfo.state = rw.State;

					Notifications.NotifyGeneric (notifyInfo);
				}
				response.RevisionWorkCompleted = rw.completed;

				using (var cmd = db.CreateCommand ()) {
					cmd.CommandText = "UPDATE Lane SET changed_date = @date WHERE id = @id;";
					DB.CreateParameter (cmd, "date", DateTime.UtcNow);
					DB.CreateParameter (cmd, "id", rw.lane_id);
					cmd.ExecuteNonQuery ();
				}

				// Check if any other lane depends on this one
				if (response.RevisionWorkCompleted) {
					using (IDbCommand cmd = db.CreateCommand ()) {
						cmd.CommandText = "SELECT 1 FROM LaneDependency WHERE dependent_lane_id = @lane_id LIMIT 1;";
						DB.CreateParameter (cmd, "lane_id", rw.lane_id);

						object value = cmd.ExecuteScalar ();
						if (value is int) {
							// If so, run the scheduler
							MonkeyWrench.Scheduler.Scheduler.ExecuteSchedulerAsync (false);
						}
					}
				}

				transaction.Commit ();
				return response;
			}
		}
		public ReportBuildStateResponse ReportBuildState (WebServiceLogin login, DBWork work)
		{
			ReportBuildStateResponse response = new ReportBuildStateResponse ();

			using (DB db = new DB ()) {
				VerifyUserInRole (db, login, Roles.BuildBot, true);
				Logger.Log (2, "ReportBuildState, state: {0}, start time: {1}, end time: {2}", work.State, work.starttime, work.endtime);
				if (work.starttime > new DateTime (2000, 1, 1) && work.endtime < work.starttime) {
					// the issue here is that the server interprets the datetime as local time, while it's always as utc.
					try {
						using (IDbCommand cmd = db.CreateCommand ()) {
							cmd.CommandText = "SELECT starttime FROM Work WHERE id = " + work.id;
							work.starttime = (DateTime) cmd.ExecuteScalar ();
						}
					} catch (Exception ex) {
						Logger.Log ("ReportBuildState: Exception while fixing timezone data: {0}", ex.Message);
					}
				}
				work.Save (db);
				work.Reload (db);

				response.Work = work;

				DBRevisionWork rw = DBRevisionWork_Extensions.Create (db, work.revisionwork_id);
				bool was_completed = rw.completed;
				rw.UpdateState (db);
				if (!was_completed && rw.completed) {
					rw.endtime = DBRecord.DatabaseNow;
					rw.Save (db);
				}
				response.RevisionWorkCompleted = rw.completed;

				MonkeyWrench.Web.WebService.Notifications.Notify (work, rw);

				return response;
			}
		}