/// <summary>
        ///    Erzeugt einen neuen Benutzer in der Datenbank anhand eines Names.
        /// </summary>
        public static User CreateUserFromUsername(DataContext db, string name)
        {
            var user = db.Users.SingleOrDefault(u => u.ShortName == name);
            if (user == null)
            {
                user = db.Users.Add(new User(name, Guid.NewGuid())
                {
                    LongName = "Anonymous User " + DateTime.Now.Second,
                    EmailAddress = "*****@*****.**",
                    IsActive = true
                });
                db.SaveChanges();
            }

            return user;
        }
		/// <summary>
		///    Verschickt Erinnerungen für Aufgaben, die bald fällig werden, oder überfällig sind.
		/// </summary>
		/// <param name="db">Ein Datenbankkontext</param>
		/// <returns>Anzahl der Aufgaben, die betrachtet wurden.</returns>
		public static string SendReminders(DataContext db)
		{
			/* Gespeichert wird in der Datenbank ja nur der Datumsanteil. Eine Aufgabe, die am Donnerstag fällig wird, enthält hier also Do, 0:00 als Zeitangabe.
			 * Tatsächlich fällig wird sie allerdings erst am Donnerstag um 24:00. Damit erklärt sich der eine Tag Unterschied in den cutoff-Daten. */

			var mailsSent = 0;
			var statusMsg = new StringBuilder();
			var mailer = new UserMailer();
			var cutoff = DateTime.Now.AddDays(6);
			var due =
				db.Assignments.Where(a => !a.IsDone && !a.ReminderSent && a.IsActive && a.DueDate < cutoff && a.Owner.IsActive)
					.ToList();
			foreach (var a in due)
			{
				// Erinnerung für Umsetzungsaufgaben nur, wenn ein Beschluss gefallen ist 
				if (a.Type == AssignmentType.ToDo || a.Topic.HasDecision(DecisionType.Resolution))
				{
					mailer.SendAssignmentReminder(a);
					a.ReminderSent = true;
					mailsSent++;
				}
			}
			db.SaveChanges();

			statusMsg.AppendFormat("Zur Erinnerung: {0} Aufgaben, {1} Erinnerungsmails versendet.\n", due.Count, mailsSent);
			mailsSent = 0;

			cutoff = DateTime.Now.AddDays(-1);
			var overdue = db.Assignments.Where(a => !a.IsDone && a.IsActive && a.DueDate < cutoff && a.Owner.IsActive).ToList();
			foreach (var a in overdue.Where(a => a.Type == AssignmentType.ToDo || a.Topic.HasDecision(DecisionType.Resolution)))
			{
				mailer.SendAssignmentOverdue(a);
				mailsSent++;
			}

			statusMsg.AppendFormat("Möglicherweise überfällig: {0}, {1} E-Mails versendet.\n", due.Count, mailsSent);

			return statusMsg.ToString();
		}
        public static User GetUser(DataContext db, IPrincipal userPrincipal)
        {
            string fullName = userPrincipal.Identity.Name;
            string shortName = fullName.Split('\\').Last();

            if (string.IsNullOrEmpty(fullName))
                return new User {ID = 0, ShortName = "xx", LongName = "Anonymous User"};

            using (var context = new PrincipalContext(ContextType.Domain, DomainName))
            using (UserPrincipal aduser = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, fullName))
            {
                if (aduser == null || aduser.Guid == null)
                    throw new AuthenticationException("Keine GUID im AD gefunden.");

                User user = db.Users.FirstOrDefault(u => u.Guid == aduser.Guid.Value);
                if (user != null)
                {
                    if (!user.IsActive)
                    {
                        user.IsActive = true;
                        db.SaveChanges();
                    }
                    return user;
                }
                else
                {
                    user = db.Users.SingleOrDefault(u => u.ShortName.Equals(shortName, StringComparison.CurrentCultureIgnoreCase));
                    if (user == null)
                    {
                        user = CreateUserFromADUser(aduser);
                        db.Users.Add(user);
                    }
                    else
                    {
                        user.Guid = aduser.Guid.Value;
                        user.LongName = aduser.DisplayName;
                        user.EmailAddress = aduser.EmailAddress;
                        user.IsActive = true;
                    }
                    db.SaveChanges();
                    return user;
                }
            }
        }
        public static void ForceReleaseLock(int documentID)
        {
            using (var db = new DataContext())
            {
                var doc = db.Documents.Find(documentID);
                var cutoff = doc.LatestRevision.Created;
                var unused = doc.Revisions.Where(r => r.Created > cutoff).ToArray();

                if (unused.Length <= 0)
                    return;

                foreach (var revision in unused)
                    System.IO.File.Delete(Path.Combine(TemporaryServerpath, revision.FileName));

                var unusedids = unused.Select(r => r.ID).ToArray();
                db.Revisions.Where(r => unusedids.Contains(r.ID)).Delete();

                doc.LockTime = null;
                doc.LockUserID = null;
                db.SaveChanges();
            }
        }