public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var header = context.OwinContext.Response.Headers.SingleOrDefault(h => h.Key == "Access-Control-Allow-Origin");

            if (header.Equals(default(KeyValuePair <string, string[]>)))
            {
                context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            }

            var form = await context.Request.ReadFormAsync();

            var tenancyName = form["tenancyName"];

            if (string.IsNullOrWhiteSpace(tenancyName))
            {
                context.SetError("invalid_company_id", "The company id is incorrect");
                //await _tenantProvider.SaveLoginAttempt(false, context.UserName, context.ErrorDescription, null, null, null);
                return;
            }

            var tenant = await _tenantProvider.GetTenantByNameAsync(tenancyName);

            if (tenant == null)
            {
                context.SetError("invalid_company_id", "The company id is incorrect");
                //await _tenantProvider.SaveLoginAttempt(false, context.UserName, context.ErrorDescription, null, null, null);
                return;
            }
            var tenantId = tenant.Id;

            var userManager = context.OwinContext.GetUserManager <UserManager>();

            userManager.SetTenantId(tenantId);

            User user = await userManager.FindAsync(tenantId, context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                await _tenantProvider.SaveLoginAttempt(false, context.UserName, context.ErrorDescription, null, null, null);

                return;
            }


            //var referer = context.Request.Headers["Referer"];
            //if (referer != null)
            //{
            //    tenancyName = TenantHelper.GetTenantNameFromReferer(referer);
            //}
            if (!string.IsNullOrWhiteSpace(tenancyName) && user.TenantName.ToLower() != tenancyName)
            {
                context.SetError("others_tenant_user", "Login failed! You are not the user of current company.");
                await _tenantProvider.SaveLoginAttempt(false, context.UserName, context.ErrorDescription, user.TenantId, user.CompanyId, user.Id);

                return;
            }


            if (!user.IsActive)
            {
                context.SetError("user_inactive", "Login failed! You are not an active user. Please contact with administration.");
                await _tenantProvider.SaveLoginAttempt(false, context.UserName, context.ErrorDescription, user.TenantId, user.CompanyId, user.Id);

                return;
            }

            bool enableEmailConfirmation;

            try
            {
                enableEmailConfirmation = Convert.ToBoolean(ConfigurationManager.AppSettings["Security:IsRequireEmailConfirmation"]);
                if (Convert.ToBoolean(enableEmailConfirmation))
                {
                    var isEmailConfirmed = await userManager.IsEmailConfirmedAsync(user.Id);

                    if (!isEmailConfirmed)
                    {
                        context.SetError("email_not_confirmed", "Your email is not confirmed.");
                        await _tenantProvider.SaveLoginAttempt(false, context.UserName, context.ErrorDescription, user.TenantId, user.CompanyId, user.Id);

                        return;
                    }
                }
            }
            catch (Exception)
            {
                context.SetError("app_setting__read_error", "Failed to read email confirmation checking setting value.");
                await _tenantProvider.SaveLoginAttempt(false, context.UserName, context.ErrorDescription, user.TenantId, user.CompanyId, user.Id);

                return;
            }


            //var tenant = await _tenantProvider.GetTenantAsync(user.TenantId);

            if (!tenant.IsActive)
            {
                context.SetError("company_inactive", "Your company is not active yet.");
                await _tenantProvider.SaveLoginAttempt(true, context.UserName, context.ErrorDescription, user.TenantId, user.CompanyId, user.Id);

                return;
            }

            var edition = await _tenantProvider.GetEditionAsync(tenant.EditionId);

            //var anyActiveSubscription = await _tenantProvider.AnyActiveSubscription(user.TenantId);
            //var anyUnpaidSubscription = await _tenantProvider.AnyUnpaidSubscription(user.TenantId);
            //var allUnpaidSubscription = await _tenantProvider.AllUnpaidSubscription(user.TenantId);

            //string lastPaymentStatus = await _tenantProvider.SubscriptionLastPaymentStatus(user.TenantId);

            var session = _sessionProvider.GetCurrentUserSession(user.Id);

            session.Application.IsEnableEmailActivation = enableEmailConfirmation;

            user.LastLoginTime = DateTime.Now;
            await userManager.UpdateAsync(user);

            await _tenantProvider.SaveLoginAttempt(true, context.UserName, context.ErrorDescription, user.TenantId, user.CompanyId, user.Id);

            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
                                                                                OAuthDefaults.AuthenticationType);

            ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                                                                                  CookieAuthenticationDefaults.AuthenticationType);

            //AuthenticationProperties properties = CreateProperties(user.UserName);
            var roles = await userManager.GetRolesAsync(user.Id);

            AuthenticationProperties properties = CreateProperties(session); //user, roles, tenant, edition, anyActiveSubscription, anyUnpaidSubscription, allUnpaidSubscription, lastPaymentStatus, enableEmailConfirmation

            AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);

            context.Validated(ticket);
            context.Request.Context.Authentication.SignIn(cookiesIdentity);
        }