public async Task<OpObject> SendMail(CMail Mail)
 {
     IsolatedContext IsoContext = new IsolatedContext();
     return await Execute(new Func<Task>(async () =>
     {
         /* Oh no, problem is STService Town, contact the organization repo */
         using (MaintienceRepository MainRepo = new MaintienceRepository())
         {
             /* Well then, lets try to create this organization */
             IsoContext.RetObj = await MainRepo.InsertMail(Mail);
         }
     }), IsoContext);
 }
        /* Create User */
        public async Task<OpObject> CreateUser(CCustomer CustomerInfo)
        {
            /* Create return object */
            IsolatedContext IsoContext = new IsolatedContext();

            /* Execute function */
            return await Execute(new Func<Task>(async () =>
            {
                using (UserRepository UserRepo = new UserRepository())
                {
                    /* Done */
                    IsoContext.RetObj = await UserRepo.Create(CustomerInfo, true);

                    /* Sanity */
                    if (IsoContext.RetObj.Code != StatusCode.Ok)
                        return;

                    /* Create a confirmation code and send the email 
                     * to the given user */
                    using (MaintienceRepository MainRepo = new MaintienceRepository()) {
                        /* Create a new confcode */
                        String uId = (String)IsoContext.RetObj.Data;
                        String ConfCode = await MainRepo.CreateCode(CodeType.Confirmation, uId);

                        /* Send a new mail */
                        IsoContext.RetObj = await MainRepo.InsertMail(new CMail() {
                            MailTo = CustomerInfo.Email,
                            Type = MailType.NoReply,
                            Subject = "NRG Models Confirmation",
                            Body = "",
                            IsHtml = false
                        });
                    }
                }
            }), IsoContext);
        }
        /* Retrieve mails waiting to be send 
         * and send them all */
        async void MailTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                /* Step 1 - Get Mails */
                List<CMail> Mails;

                using (MaintienceRepository MaintienceRepo = new MaintienceRepository())
                {
                    Mails = await MaintienceRepo.GetMails();
                }

                if (Mails.Count != 0)
                    Log("Sending " + Mails.Count.ToString() + " Mails");
                else
                    return;

                /* Step 2 - Iterate & Send */
                using (MaintienceRepository MaintienceRepo = new MaintienceRepository())
                {
                    foreach (CMail Mail in Mails)
                    {
                        try
                        {
                            /* Parse if multiple */
                            List<String> Recipients = null;
                            if (Mail.MailTo.Contains(";"))
                            {
                                String[] MailTokens = Mail.MailTo.Split(new Char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                                Recipients = new List<String>(MailTokens);
                            }
                            else
                            {
                                Recipients = new List<String>();
                                Recipients.Add(Mail.MailTo);
                            }

                            /* Build Mail */
                            SendGridMessage sMail = new SendGridMessage();

                            foreach (String MailStr in Recipients)
                            {
                                String Trimmed = MailStr.Trim();
                                if (!String.IsNullOrEmpty(Trimmed))
                                {
                                    try { sMail.AddTo(Trimmed); }
                                    catch (Exception) { }
                                }
                            }

                            /* Sanity */
                            if (sMail.To.Length != 0)
                            {
                                if (Mail.Type == MailType.NoReply)
                                    sMail.From = new System.Net.Mail.MailAddress("*****@*****.**", "PatchIT");
                                else if (Mail.Type == MailType.Billing)
                                    sMail.From = new System.Net.Mail.MailAddress("*****@*****.**", "PatchIT");
                                else
                                    sMail.From = new System.Net.Mail.MailAddress("*****@*****.**", "PatchIT");

                                sMail.Subject = Mail.Subject;
                                sMail.Html = Mail.Body;
                                sMail.Text = Mail.Body;

                                /* Send it */
                                await sClient.DeliverAsync(sMail);
                            }

                            /* Delete Mail */
                            await MaintienceRepo.DeleteMail(Mail.Id);
                        }
                        catch (Exception Ex)
                        {
                            /* Dunno how to handle this really, delete it? */
                            Log(Ex.ToString());
                        }
                    }
                }
            }
            catch (Exception ExUpper)
            {
                Log(ExUpper.ToString());
            }
        }
        private async Task<OpObject> Execute(Func<Task> a, IsolatedContext IsoContext)
        {
            try
            {
                /* Convert session -> guid? */
                if (IsoContext.SessionId != "0")
                {
                    using (MaintienceRepository MainRepo = new MaintienceRepository())
                    {
                        String Result = await MainRepo.IsSessionValid(IsoContext.SessionId);

                        /* Sanity */
                        if (Result == "0")
                            return new OpObject(StatusCode.InvalidSession, "SessionId was invalid");
                        else
                            IsoContext.uGuid = Result;
                    }
                }

                /* Run function */
                await a.Invoke();

                /* Done */
                return IsoContext.RetObj;
            }
            catch (DbEntityValidationException Ex)
            {
                /* Get all validation errors */
                var ErrMsgs = Ex.EntityValidationErrors
                        .SelectMany(x => x.ValidationErrors)
                        .Select(x => x.ErrorMessage);

                /* Combine them */
                String FullErrMsgs = String.Join("; ", ErrMsgs);

                /* Create a new exception message */
                String ExMsg = String.Concat(Ex.Message, " The validation errors are: ", FullErrMsgs);

                /* Return it */
                return new OpObject(StatusCode.InvalidParameters, ExMsg);
            }
            catch (OptimisticConcurrencyException Ex)
            {
                /* Return a try-again */
                return new OpObject(StatusCode.TryAgain, Ex.ToString());
            }
            catch (DbUpdateException Ex)
            {
                return new OpObject(StatusCode.TryAgain, Ex.ToString());
            }
            catch (Exception Ex)
            {
                /* Invalid Params? */
                if (Ex is NullReferenceException ||
                    Ex is ArgumentNullException ||
                    Ex is ArgumentException ||
                    Ex is ArgumentOutOfRangeException)
                {
                    /* Return a arg-exception */
                    return new OpObject(StatusCode.InvalidParameters, Ex.ToString());
                }

                /* Return fault */
                return new OpObject(StatusCode.FuckedUp, Ex.ToString());
            }
        }
        /* Logout */
        public async Task<OpObject> Logout(String SessionId)
        {
            StatusCode RetCode;

            /* Just delete us from instance manager */
            using (MaintienceRepository MainRepo = new MaintienceRepository())
            {
                RetCode = await MainRepo.DeleteSessionId(SessionId);
            }

            /* Done */
            return new OpObject(RetCode);
        }
        /* Login */
        public async Task<OpObject> Login(String eMail, String Password)
        {
            /* Create return object */
            IsolatedContext IsoContext = new IsolatedContext();

            /* Execute function */
            return await Execute(new Func<Task>(async () =>
            {
                using (UserRepository UserRepo = new UserRepository())
                {
                    /* Does password and email match? */
                    IsoContext.RetObj = await UserRepo.TestPassword(eMail, Password);

                    /* Return ConfCode */
                    using (MaintienceRepository MainRepo = new MaintienceRepository())
                    {
                        /* Very Sanity */
                        if (IsoContext.RetObj.Code == StatusCode.UserNotConfirmed)
                        {
                            /* Lookup */
                            String ConfCode =
                                await MainRepo.GetCode(CodeType.Confirmation, (String)IsoContext.RetObj.Data);

                            /* Sanity */
                            if (ConfCode == "0")
                            {
                                ConfCode = await MainRepo.CreateCode(CodeType.Confirmation,
                                    (String)IsoContext.RetObj.Data);
                            }

                            /* Set */
                            IsoContext.RetObj.Data = ConfCode;
                        }

                        /* Sanity */
                        if (IsoContext.RetObj.Code != StatusCode.Ok)
                            return;

                        /* Are we logged in already? */
                        String SessionId = await MainRepo.HasSession((String)IsoContext.RetObj.Data);

                        if (SessionId != "0")
                        {
                            IsoContext.RetObj = new OpObject(StatusCode.Ok, SessionId);
                            return;
                        }

                        /* No, create a session */
                        IsoContext.RetObj.Data = await MainRepo.CreateSessionId((String)IsoContext.RetObj.Data);
                    }
                }
            }), IsoContext);
        }
        /* Validate SessionId */
        public async Task<bool> ValidateSessionId(String SessionId)
        {
            using (MaintienceRepository MainRepo = new MaintienceRepository())
            {
                String Result = await MainRepo.IsSessionValid(SessionId);

                /* Sanity */
                return (Result == "0") ? false : true;
            }
        }
        /* Confirm User */
        public async Task<OpObject> ConfirmUser(String ConfirmationId)
        {
            /* Create return object */
            IsolatedContext IsoContext = new IsolatedContext();

            /* Execute function */
            return await Execute(new Func<Task>(async () =>
            {
                /* Get user guid */
                String uGuid = "0";
                using (MaintienceRepository MainRepo = new MaintienceRepository())
                {
                    /* Delete */
                    uGuid = await MainRepo.DeleteCode(ConfirmationId);
                }

                /* Sanity */
                if (uGuid == "0")
                {
                    IsoContext.RetObj = new OpObject(StatusCode.InvalidParameters);
                    return;
                }

                /* Access user repo */
                using (UserRepository UserRepo = new UserRepository())
                {
                    /* Confirm the user */
                    IsoContext.RetObj = await UserRepo.Confirm(uGuid);
                }
            }), IsoContext);
        }
        /* Forgot Password */
        public async Task<OpObject> ForgotPassword(String eMail)
        {
            /* Create return object */
            IsolatedContext IsoContext = new IsolatedContext();

            /* Execute function */
            return await Execute(new Func<Task>(async () =>
            {
                using (UserRepository UserRepo = new UserRepository())
                {
                    /* Done */
                    IsoContext.RetObj = await UserRepo.GetGuid(eMail);

                    /* Sanity */
                    if (IsoContext.RetObj.Code != StatusCode.Ok)
                        return;

                    /* Get confirmation code */
                    using (MaintienceRepository MainRepo = new MaintienceRepository())
                    {
                        String ConfCode = await MainRepo.CreateCode(CodeType.Recovery,
                            (String)IsoContext.RetObj.Data);

                        /* Save it */
                        IsoContext.RetObj.Data = ConfCode;
                    }
                }
            }), IsoContext);
        }