public async Task <LoginResponseModel> PostLogin(LoginRequestModel model)
        {
            // Get DeviceTag
            var deviceTagResult = LocalDeviceTag;

            if (deviceTagResult.HasLogTag(LogTag.MissingDeviceTag))
            {
                Log.Reports(deviceTagResult.Reports, Request);
                return(LoginResponseModel.InvalidEntry);
            }
            var deviceTag = deviceTagResult.Value;

            if (!ModelState.IsValid)
            {
                Log.Error(LogTag.InvalidLogInModelState, Request, new { message = ModelState.Values, model });
                return(LoginResponseModel.InvalidEntry);
            }

            var aspNetUser = await UserManager.FindByNameAsync(model.UserName);

            if (aspNetUser == null)
            {
                Log.Info(LogTag.AttemptToLogInWithUnknownUserName, Request, new { model.UserName });
                return(LoginResponseModel.UnrecognizedEmailOrPassword);
            }
            var user = aspNetUser.Users.First();

            if (user.Status.Id == UserStatuses.Deleted)
            {
                Log.Info(LogTag.AttemptToLogInWithInvalidUser, Request, new { userId = user.Id, status = user.Status.Value });
                return(LoginResponseModel.UnrecognizedEmailOrPassword);
            }

            var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, true, false);

            if (result != SignInStatus.Success)
            {
                Log.Info(LogTag.LogInFailed, Request, new { status = result, model });
                return(LoginResponseModel.UnrecognizedEmailOrPassword);
            }

            // Update LastVisit date.
            LastVisitHelper.SaveUserLastVisit(model.UserName, Request);

            // Link device to new user
            await DeviceTagManager.LinkDeviceToUser(deviceTag, user.Id);

            // Log success
            Log.Info(LogTag.LogInSuccess, Request, new { userId = user.Id, status = user.Status.Value });
            return(new LoginResponseModel {
                IsAuthenticated = true
            });
        }
        public async Task <SignUpResponseModel> SignUp(SignUpRequestModel model)
        {
            // Get DeviceTag
            var deviceTagResult = LocalDeviceTag;

            if (deviceTagResult.HasLogTag(LogTag.MissingDeviceTag))
            {
                Log.Reports(deviceTagResult.Reports, Request);
                return(SignUpResponseModel.InvalidEntry);
            }
            var deviceTag = deviceTagResult.Value;

            //Get IpAddress
            var clientIpAddress = NetHelper.GetClientIpAddressFrom(Request);

            // Validate model
            if (ModelState.IsValid == false)
            {
                Log.Error(LogTag.InvalidSignUpModelState, Request, new { message = ModelState.Values, model });
                return(SignUpResponseModel.InvalidEntry);
            }
            // Verify email isn't already used
            if ((await UserManager.FindByNameAsync(model.Email)) != null)
            {
                Log.Info(LogTag.SignUpEmailAlreadyInUse, Request, new { model.Email });
                return(SignUpResponseModel.EmailAlreadyInUse);
            }
            // Create AspNet user
            var aspNetUser = new AspNetUser {
                UserName = model.Email, Email = model.Email, UiCulture = System.Threading.Thread.CurrentThread.CurrentUICulture.Name
            };
            var result = await UserManager.CreateAsync(aspNetUser, model.Password);

            if (!result.Succeeded)
            {
                Log.Error(LogTag.AspNetUserCreationError, Request, new { result.Errors });
                return(SignUpResponseModel.UnhandledIssue);
            }

            // Regulate new user
            var user = await UserFromSignUpModel(model, aspNetUser.Id);

            IAccountRegulator regulator = Injection.Kernel.Get <IAccountRegulator>();
            var logReports = regulator.RegulateNewUser(model.Email, model.Password, user, deviceTag, clientIpAddress);

            Log.Reports(logReports, Request);

            //Save Hellolingo user profile
            var newUser = await StoreNewUser(user);

            if (newUser == null)
            {
                Log.Error(LogTag.SignUpUserCreationReturnedNull, Request, new { aspNetUser, model });
                await UserManager.DeleteAsync(aspNetUser);

                return(SignUpResponseModel.UnhandledIssue);
            }

            // Complete non-critical sign up process
            try {
                // Link device to new user
                var ipV4 = NetHelper.GetClientIpAddressAsUIntFrom(Request);
                await DeviceTagManager.LinkDeviceToUser(deviceTag, newUser.Id);

                // Send Email Verification
                if (newUser.StatusId == UserStatuses.PendingEmailValidation)
                {
                    await SendConfirmationEmailAsync(aspNetUser, newUser, aspNetUser.Email);
                }

                // Add Welcome Mail
                string message;
                switch (CultureHelper.GetCurrentCulture())
                {
                case "fr": message = "\n\nNous sommes ravis de vous compter comme nouveau membre de notre communauté. Nous vous recommandons d’explorer la fonction de recherche de partenaires linguistiques et d’envoyer autant d'emails que vous le souhaitez à des partenaires potentiels. Ils vous répondront ici dans votre messagerie. Vous pouvez aussi vous rendre dans la section de chat vocal et textuel pour commencer à pratiquer tout de suite dans les salons de chat publiques et privés (la fonction chat vocal est disponible en conversation privée)." +
                                     "\n\nSi vous avez des soucis, des questions ou des idées, n’hésitez pas à nous contacter via le formulaire de contact ou en répondant directement à cet email. HelloLingo est votre communauté et nous comptons sur vous pour la garder conviviale.Veillez à vous en servir dans un but d’apprentissage linguistique uniquement, soyez respectueux et pensez à reporter les bugs et dérangements quand vous les voyez. C’est la meilleure façon de protéger et d’améliorer HelloLingo." +
                                     "\n\nApprenez et prospérez !\nL’équipe HelloLingo"; break;

                case "de": message = "\n\nWir sind erfreut, dich als neues Mitglied unserer Sprachlern - Gemeinschaft zu begrüßen. Wir empfehlen dir die Finden - Funktion zu erkunden und so viele Emails an potentielle Partner zu versenden wie du möchtest. Sie werden dir genau hier antworten, in deiner Mailbox. Du kannst auch zum Text & Voice Chat gehen und sofort beginnen, in öffentlichen oder privaten Räumen zu lernen. Voice Chat Unterhaltungen können von einem beliebigen privaten Raum gestartet werden." +
                                     "\n\nSolltest du Probleme, Fragen oder Anregungen haben, lass es uns bitte wissen. Dafür kannst du das Kontaktformular benutzen oder direkt auf diese Email antworten. Hellolingo ist deine Community und wir zählen auf deinen Beitrag dazu, dass sie großartig bleibt. Bitte verwende sie nur zum Sprachen lernen, sei rücksichtsvoll und denke darüber nach, Störungen oder Fehler zu melden, sobald du sie siehst.Das ist der beste Weg, um Hellolingo zu bewahren und zu verbessern." +
                                     "\n\nLearn and prosper!\nThe Hellolingo Team"; break;

                case "ko": message = "\n\n우리는 귀하가 언어습득 모임의 새 회원이 되신것을 매우 반갑게 생각합니다. 당신이 우리의 다양한 기능을 탐색해 보고 잠재적 파트너에게 많은 이메일을 보내시는것을 추천합니다. 그들은 당신의 메일박스에 회신할 것입니다. 또한 텍스트&보이스 채팅에서 오픈된 혹은 개인적 채팅룸에서 즉시 연습하실수 있습니다. " +
                                     "\n\n만일 다른 사항, 질문 혹은 아이디어가 있으시면 이 이메일로 회신을 주시면 감사하겠습니다. Hellolingo는 당신의 커뮤니티이고 항상 멋지게 유지되길 기대하고 있습니다. 반드시 이 사이트는 언어를 배우는 것으로만 사용해 주시고 다른이들을 배려하며 불편사항이나 버그를 발견하시면 말씀해 주시기 바랍니다. 이것은 Hellolingo를 보호하고 발전시키는 가장 좋은 방법입니다. " +
                                     "\n\n배우고 발전하자!\nHellolingo 팀 드림"; break;

                case "nl": message = "\n\nWe zijn heel verheugd om jou als een nieuwe deelnemer in onze gemeenschap te mogen verwelkomen.We raden je aan om vooral de find feature uit te proberen, en zoveel mogelijk e - mails te versturen naar potentiele partners.Ze zullen je hier beantwoorden, in jouw mailbox. Je kan ook naar de tekst&voice chat gaan en direct beginnen met oefenen in publieke of privé kamers. Chats met voice gesprekken kunnen geïnitieerd worden vanuit elke privé kamer." +
                                     "\n\nAls je enige problemen, vragen of ideeën hebt, laat het ons alstublieft weten via onze contact formulier, of door direct op deze e-mail te reageren. Hellolingo is jouw gemeenschap en we rekenen op jou om het aangenaam te houden.Zorg ervoor dat je het alleen gebruikt om talen te oefenen, altijd rekening houdt met anderen en niet vergeet om onderbrekingen en bugs te rapporteren wanneer je die ervaart. Dit is de beste manier waarop Hellolingo beschermt en verbetert kan worden." +
                                     "\n\nLeer en wees succesvol!\nHet Hellolingo Team"; break;

                case "zh-CN": message = "\n\n非常开心你能加入我们的语言学习社区。我们希望你能尽可能的去探索和尝试各种功能,你可以随时发邮件给你的潜在语言搭档,他们的回复会出现在你的邮箱里。你也可以使用文本 & 语音聊天功能在公共聊天室或者私人聊天室立刻开始进行你的语言练习。任何私人聊天室都是可以进行语音对话的。" +
                                        "\n\n如果你有任何疑问, 建议或者想法,请随时通过上述联系方式来联系我们。hellolingo是属于你的语言社区,你有责任把它变的越来越好,不是吗?:-)同时,我们希望你在这里进行的只有语言学习这一件事,也请在学习的同时,去关心和体谅他人。如果你遇到了任何bug,请及时反馈给我们,这是让hellolingo能更好的为你服务的最佳方式。" +
                                        "\n祝:学习进步,生活开心。\n\nhellolingo团队敬上"; break;

                default: message = "\n\nWe're thrilled to have you as a new member of our language learning community. We recommend you to explore the Find feature and send as many emails as you want to potential partners. They'll reply to you right here, in you mailbox. You can also go to the Text & Voice chat and start practicing immediately in public or private rooms. Voice chat conversations can be initiated from any private room." +
                                   "\n\nIf you have any issues, questions or ideas, please let us know from the contact form or by replying to this email directly. Hellolingo is your community and we count on you to keep it awesome. Make sure to use it for language learning only, always be considerate of others and think about reporting disruptions or bugs when you see them. This is the best way to protect and improve Hellolingo." +
                                   "\n\nLearn and prosper!\nThe Hellolingo Team"; break;
                    //"\n\nP.S.: We're looking to translate this message in the following languages: 日本語. Email us if you can help.";
                }
                Entity.Mails.Add(new Mail {
                    When             = DateTime.Now,
                    FromId           = 1, ToId = user.Id, FromStatus = MailStatuses.Deleted, ToStatus = MailStatuses.New,
                    RegulationStatus = MailRegulationStatuses.ManualPass, NotifyStatus = NotifyStatuses.Blocked,
                    Subject          = "Welcome to Hellolingo!", Message = message, ReplyToMail = null
                });
                await Entity.SaveChangesAsync();
            } catch (Exception ex) {
                Log.Error(LogTag.CompletingSignUpFailed, Request, new { aspNetUser, model, ex });
            }

            // Sign new user in
            return(await SignInCreatedUser(aspNetUser.Id));
        }